diff -rNci gcc-2.7.2/combine.c gcc-2.7.2p/combine.c
*** gcc-2.7.2/combine.c	Sun Nov 26 19:32:07 1995
--- gcc-2.7.2p/combine.c	Tue Jan 23 09:53:17 1996
***************
*** 97,102 ****
--- 97,106 ----
  #include "recog.h"
  #include "real.h"
  
+ /* intel1 */
+ static int in_recombine=0;
+ extern FILE *combine_dump_file;
+ 
  /* It is not safe to use ordinary gen_lowpart in combine.
     Use gen_lowpart_for_combine instead.  See comments there.  */
  #define gen_lowpart dont_use_gen_lowpart_you_dummy
***************
*** 386,391 ****
--- 390,418 ----
  
  static int n_occurrences;
  
+ /* intel2 - begin */
+ 
+ #define INSN_SETS_REGNO(INSN, REGNO) dead_or_set_regno_p (INSN, REGNO)
+ #define INSN_USES_REGNO(INSN, REGNO) refers_to_regno_p (REGNO, \
+ 							REGNO + 1, \
+                                                         PATTERN (INSN), \
+                                                         0)
+ 
+ /* if this flag is set do not recombine unscheded riscified insns, which their
+  * original insn's destination was a memory.
+  */
+ extern int flag_risc_mem_dest;
+ 
+ /* if this flag is set try to riscify stores of CONST_INTs */
+ extern int flag_risc_const;
+ 
+ void update_free_regs (rtx);
+ static void update_regno_holds_mem (rtx insn, rtx pat);
+ static int remove_redundant_store (rtx mem, int block);
+ static void update_entries (rtx reg);
+ 
+ /* intel2 - end */
+ 
  static void init_reg_last_arrays	PROTO(());
  static void setup_incoming_promotions   PROTO(());
  static void set_nonzero_bits_and_sign_copies  PROTO((rtx, rtx));
***************
*** 445,450 ****
--- 472,486 ----
  static void distribute_notes	PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
  static void distribute_links	PROTO((rtx));
  static void mark_used_regs_combine PROTO((rtx));
+ static int try_forwards_replace PROTO((rtx, rtx, rtx, FILE *));
+ /* intel2 */
+ #if 0
+ static void dump_free_registers ();
+ #endif
+ int find_free_reg();
+ static int find_regno_holds_mem (rtx, enum machine_mode);
+ /* intel1 */
+ static int try_backwards_replace ();
  
  /* Main entry point for combiner.  F is the first insn of the function.
     NREGS is the first unused pseudo-reg number.  */
***************
*** 881,886 ****
--- 917,925 ----
  
    /* Don't eliminate a store in the stack pointer.  */
    if (dest == stack_pointer_rtx
+       /* intel1 
+       || (in_recombine && GET_CODE (dest) == REG
+           && reg_used_between_p (dest, insn, i3)) */
        /* If we couldn't eliminate a field assignment, we can't combine.  */
        || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
        /* Don't combine with an insn that sets a register to itself if it has
***************
*** 1059,1064 ****
--- 1098,1105 ----
     On machines where SMALL_REGISTER_CLASSES is defined, we don't combine
     if the destination of a SET is a hard register that isn't a user
     variable.
+    intel2 - This is true unless we are in recombine (indicated by
+    in_recombine)
  
     Before doing the above check, we first try to expand a field assignment
     into a set of logical operations.
***************
*** 1128,1139 ****
--- 1169,1194 ----
  	     CALL operation.  */
  	  || (GET_CODE (inner_dest) == REG
  	      && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
+ 	      /* intel2 - begin */
+ 	      /* if we are in the recombine phase, we should not eliminate the
+ 	       * possibility for combine if the destination is a hard register.
+ 	       */
+ 	      && (!in_recombine)
+ 	      /* intel2 - end */
  	      && (! HARD_REGNO_MODE_OK (REGNO (inner_dest),
  					GET_MODE (inner_dest))
  #ifdef SMALL_REGISTER_CLASSES
  		 || (GET_CODE (src) != CALL && ! REG_USERVAR_P (inner_dest))
  #endif
  		  ))
+ 
+       /* intel2 - begin */
+       /* if we want to leave mem-dest riscified instructions untouched... */
+       || (in_recombine
+ 		&& flag_risc_mem_dest
+ 		&& GET_CODE (inner_dest) == MEM)
+       /* intel2 - end */
+ 
  	  || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src)))
  	return 0;
  
***************
*** 1389,1394 ****
--- 1444,1468 ----
        return 0;
      }
  
+   /* intel1 */
+   if (in_recombine)
+     {
+       if (i1 && GET_CODE (PATTERN (i1)) == SET 
+           && GET_CODE (SET_DEST (PATTERN (i1))) == REG
+           && reg_used_between_p (SET_DEST (PATTERN (i1)), i1, i2))
+         {
+           undo_all ();
+           return 0;
+         }
+       if (i2 && GET_CODE (PATTERN (i2)) == SET 
+           && GET_CODE (SET_DEST (PATTERN (i2))) == REG
+           && reg_used_between_p (SET_DEST (PATTERN (i2)), i2, i3))
+         {
+           undo_all ();
+           return 0;
+         }
+     }
+ 
    /* Record whether I2DEST is used in I2SRC and similarly for the other
       cases.  Knowing this will help in register status updating below.  */
    i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
***************
*** 2021,2026 ****
--- 2095,2142 ----
  	  = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches);
      }
  
+    /* intel1 , maybe we can rearrange memory so it is recognized */
+ #ifdef REWRITE_ADDRESS
+    if (insn_code_number==-1 && GET_CODE(newpat)==SET && i1==NULL)
+      {
+        rtx copy_of_newpat,try_to_make_good(); /* see loop.c */
+        rtx new_src_copy,new_dest_copy;
+        int dummy;
+        char * storage;
+        storage = (char *) oballoc(0);
+        copy_of_newpat = copy_rtx (newpat);
+        new_src_copy = SET_SRC (copy_of_newpat);
+        try_to_make_good (SET_SRC (copy_of_newpat));
+        try_to_make_good (SET_DEST (copy_of_newpat));
+        if (recog (copy_of_newpat, i3, &dummy) != -1)
+          {
+            int scrat;
+            newpat = copy_of_newpat;
+            insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes, &scrat);
+          }
+        else if (GET_CODE (new_src_copy) != MEM)
+          {
+            new_src_copy = gen_rtx (MEM, GET_MODE( new_src_copy), new_src_copy);
+            try_to_make_good (new_src_copy);
+            SET_SRC (copy_of_newpat) = XEXP (new_src_copy,0);
+            if (recog (copy_of_newpat,i3,&dummy) != -1)
+              {
+                int scrat;
+                newpat = copy_of_newpat;
+                insn_code_number = recog_for_combine (&newpat,i3,&new_i3_notes,&scrat);
+              }
+            else
+              {
+                obfree (storage);
+              }
+          }
+        else
+          {
+            obfree (storage);
+          }
+      }
+ #endif /* REWRITE_ADDRESS */
+ 
    /* If it still isn't recognized, fail and change things back the way they
       were.  */
    if ((insn_code_number < 0
***************
*** 2031,2036 ****
--- 2147,2176 ----
        return 0;
      }
  
+  /* intel2 - begin */
+ #ifdef REGISTER_CONSTRAINTS
+    /* check if the combined insn is a legal one */
+    if (in_recombine)
+      {
+        register rtx temp_pat = PATTERN (i3);
+        register int temp_code_number = INSN_CODE (i3);
+ 
+        /* change it only for the following check */
+        PATTERN (i3) = newpat;
+        INSN_CODE (i3) = insn_code_number;
+        insn_extract (i3);
+        /* restore the data */
+        PATTERN (i3) = temp_pat;
+        INSN_CODE (i3) = temp_code_number;
+        if (! constrain_operands (insn_code_number, 1))
+          {
+            undo_all();
+            return 0;
+          }
+      }
+ #endif
+  /* intel2 - end */
+ 
    /* If we had to change another insn, make sure it is valid also.  */
    if (undobuf.other_insn)
      {
***************
*** 4248,4253 ****
--- 4388,4401 ----
        int other_changed = 0;
        enum machine_mode compare_mode = GET_MODE (dest);
  
+     /* intel1 */
+ #ifdef HAVE_cc0
+     if(SET_DEST (x) == cc0_rtx && compare_mode==VOIDmode)
+       {
+         compare_mode = GET_MODE (SET_SRC (x));
+       }
+ #endif
+ 
        if (GET_CODE (src) == COMPARE)
  	op0 = XEXP (src, 0), op1 = XEXP (src, 1);
        else
***************
*** 9912,9918 ****
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      {
        if (REG_NOTE_KIND (link) == REG_DEAD
! 	  && GET_CODE (XEXP (link, 0)) == REG)
  	{
  	  int regno = REGNO (XEXP (link, 0));
  	  int endregno
--- 10060,10072 ----
    for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
      {
        if (REG_NOTE_KIND (link) == REG_DEAD
!           /* intel2 - begin */
!           /* if in_recombine we might encounter a REG_DEAD note of memory!
!            */
!           && (! in_recombine
!               || GET_CODE (XEXP (link, 0)) == REG)
!           /* intel2 - end */
!       	 )
  	{
  	  int regno = REGNO (XEXP (link, 0));
  	  int endregno
***************
*** 10755,10806 ****
  
  	  if (place == 0)
  	    {
! 	      for (tem = prev_nonnote_insn (i3);
  		   place == 0 && tem
  		   && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN);
  		   tem = prev_nonnote_insn (tem))
! 		{
! 		  /* If the register is being set at TEM, see if that is all
! 		     TEM is doing.  If so, delete TEM.  Otherwise, make this
! 		     into a REG_UNUSED note instead.  */
! 		  if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
! 		    {
! 		      rtx set = single_set (tem);
  
! 		      /* Verify that it was the set, and not a clobber that
! 			 modified the register.  */
  
! 		      if (set != 0 && ! side_effects_p (SET_SRC (set))
! 			  && (rtx_equal_p (XEXP (note, 0), SET_DEST (set))
! 			      || (GET_CODE (SET_DEST (set)) == SUBREG
! 				  && rtx_equal_p (XEXP (note, 0),
! 						  XEXP (SET_DEST (set), 0)))))
! 			{
! 			  /* Move the notes and links of TEM elsewhere.
! 			     This might delete other dead insns recursively. 
! 			     First set the pattern to something that won't use
! 			     any register.  */
! 
! 			  PATTERN (tem) = pc_rtx;
! 
! 			  distribute_notes (REG_NOTES (tem), tem, tem,
! 					    NULL_RTX, NULL_RTX, NULL_RTX);
! 			  distribute_links (LOG_LINKS (tem));
! 
! 			  PUT_CODE (tem, NOTE);
! 			  NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
! 			  NOTE_SOURCE_FILE (tem) = 0;
! 			}
! 		      else
! 			{
! 			  PUT_REG_NOTE_KIND (note, REG_UNUSED);
! 			  
! 			  /*  If there isn't already a REG_UNUSED note, put one
! 			      here.  */
! 			  if (! find_regno_note (tem, REG_UNUSED,
! 						 REGNO (XEXP (note, 0))))
! 			    place = tem;
! 			  break;
  		      }
  		  }
  		else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
--- 10909,10973 ----
  
  	  if (place == 0)
  	    {
! 	    for (tem = prev_nonnote_insn (i3);
  		   place == 0 && tem
  		   && (GET_CODE (tem) == INSN || GET_CODE (tem) == CALL_INSN);
  		   tem = prev_nonnote_insn (tem))
! 	      {
! 		/* If the register is being set at TEM, see if that is all
! 		   TEM is doing.  If so, delete TEM.  Otherwise, make this
! 		   into a REG_UNUSED note instead.  */
! 		if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
! 		  {
! 		    rtx set = single_set (tem);
  
! 		    /* Verify that it was the set, and not a clobber that
! 		       modified the register.  */
  
! 		    if (set != 0 && ! side_effects_p (SET_SRC (set))
!  			&& (rtx_equal_p (XEXP (note, 0), SET_DEST (set))
!  			    || (GET_CODE (SET_DEST (set)) == SUBREG
!  				&& rtx_equal_p (XEXP (note, 0),
!  						XEXP (SET_DEST (set), 0)))))
! 		      {
! 			/* Move the notes and links of TEM elsewhere.
! 			   This might delete other dead insns recursively. 
! 			   First set the pattern to something that won't use
! 			   any register.  */
! 
! 			PATTERN (tem) = pc_rtx;
! 
! 			distribute_notes (REG_NOTES (tem), tem, tem,
! 					  NULL_RTX, NULL_RTX, NULL_RTX);
! 			distribute_links (LOG_LINKS (tem));
! 
! 			PUT_CODE (tem, NOTE);
! 			NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED;
! 			NOTE_SOURCE_FILE (tem) = 0;
! 		      }
! 		    else
! 		      {
!               /* intel1 making this into reg_unused causes
!                  bug in scheduler since sched will see this
!                  as a reg_dead */
! #if 0
! 			PUT_REG_NOTE_KIND (note, REG_UNUSED);
! #endif
! 
! #if 0
! 			/*  If there isn't already a REG_UNUSED note, put one
! 			    here.  */
! 			if (! find_regno_note (tem, REG_UNUSED,
! 					       REGNO (XEXP (note, 0))))
! 			  place = tem;
! #else
!           /*  If there isn't already a REG_DEAD note, put one
!               here.  */
!           if (! find_regno_note (tem, REG_DEAD,
!                          REGNO (XEXP (note, 0))))
!             place = tem;
! #endif
! 			break;
  		      }
  		  }
  		else if (reg_referenced_p (XEXP (note, 0), PATTERN (tem))
***************
*** 10826,10832 ****
  		      }
  		    break;
  		  }
! 		}
  	      
  	      /* If we haven't found an insn for the death note and it
  		 is still a REG_DEAD note, but we have hit a CODE_LABEL,
--- 10993,10999 ----
  		      }
  		    break;
  		  }
! 	      }
  	      
  	      /* If we haven't found an insn for the death note and it
  		 is still a REG_DEAD note, but we have hit a CODE_LABEL,
***************
*** 11100,11103 ****
--- 11267,13846 ----
      (file,
       "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
       total_attempts, total_merges, total_extras, total_successes);
+ }
+ 
+ /* intel1 */
+ /* intel1 - those split insns that remained consecutive should now
+            be combined 
+ */
+ void
+ combine_unscheded (f, nregs)
+      rtx f;
+      int nregs;
+ {
+   register rtx insn, next, prev;
+   register int i;
+   register rtx links, nextlinks, note;
+ 
+   in_recombine = 1;
+   combine_attempts = 0;
+   combine_merges = 0;
+   combine_extras = 0;
+   combine_successes = 0;
+ 
+   combine_max_regno = nregs;
+ 
+   reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
+   reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
+   reg_last_set_value = (rtx *) alloca (nregs * sizeof (rtx));
+   reg_last_set_table_tick = (int *) alloca (nregs * sizeof (int));
+   reg_last_set_label = (int *) alloca (nregs * sizeof (int));
+   reg_last_set_invalid = (char *) alloca (nregs * sizeof (char));
+ 
+   bzero (reg_last_death, nregs * sizeof (rtx));
+   bzero (reg_last_set, nregs * sizeof (rtx));
+   bzero (reg_last_set_value, nregs * sizeof (rtx));
+   bzero (reg_last_set_table_tick, nregs * sizeof (short));
+   bzero (reg_last_set_invalid, nregs * sizeof (char));
+ 
+   init_recog_no_volatile ();
+ 
+   /* Compute maximum uid value so uid_cuid can be allocated.  */
+ 
+   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
+     if (INSN_UID (insn) > i)
+       i = INSN_UID (insn);
+ 
+   uid_cuid = (int *) alloca ((i + 1) * sizeof (int));
+ 
+   /* Compute the mapping from uids to cuids.
+      Cuids are numbers assigned to insns, like uids,
+      except that cuids increase monotonically through the code. 
+ 
+      Scan all SETs and see if we can deduce anything about what
+      bits are significant for some registers.  */
+ 
+   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
+     {
+       uid_cuid [INSN_UID (insn)] = ++i;
+       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ 	note_stores (PATTERN (insn), set_nonzero_bits_and_sign_copies);
+     }
+ 
+ 
+   label_tick = 1;
+   last_call_cuid = 0;
+   mem_last_set = 0;
+   /* Now scan all the insns in forward order.  */
+   for (insn = f; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == CODE_LABEL)
+ 	label_tick++;
+       if(GET_CODE (insn) == INSN)
+ 	{
+ 	  /* Try this insn with each insn it links back to.  */
+ 	  for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
+ 	    {
+ 	      if(REG_NOTE_KIND (links) != REG_DEP_ANTI 
+ 	         /*&& REG_NOTE_KIND (links) != REG_DEP_OUTPUT 
+ 	         && */ && (GET_CODE (XEXP (links, 0)) == INSN 
+ 	              && next_nonnote_insn (XEXP (links, 0))
+ 	                   == ORG_NEXT_INSN (XEXP (links, 0)))
+ 	         && GET_CODE (PATTERN (XEXP (links, 0))) == SET
+ 	         && GET_CODE (SET_DEST (PATTERN (XEXP (links, 0))))
+ 	              == REG
+ 	         && (note
+ 	              = find_regno_note (insn,
+ 	                                 REG_DEAD,
+ 	                  REGNO(SET_DEST (PATTERN (XEXP (links, 0))))))
+ 	         && rtx_equal_p (XEXP (note, 0),
+ 	                          SET_DEST (PATTERN (XEXP (links, 0))))
+ 		 /* intel2 - begin */
+ 		 /* combine only insns that were created by memory_simplify.
+ 		  */
+ 		 && (RTX_IS_RISC_P (XEXP (links, 0)))
+ 		 /* intel2 - end */
+ 	        )
+ 	        {
+ 		  /* intel2 - begin */
+ 		  rtx inner_link = LOG_LINKS (XEXP (links, 0));
+ 		  int three_insns = 0;
+ 
+ 		  /* Check that we consider the case of three-insns riscified
+ 		   * insn
+ 		   */
+ 		  if (inner_link)
+ 		    {
+ 		      for (; inner_link; inner_link = XEXP (inner_link, 1))
+ 		        {
+ 		          rtx temp_insn = XEXP (inner_link, 0);
+ 
+ 		          if (REG_NOTE_KIND (inner_link) != REG_DEP_ANTI
+ 		              /*&& REG_NOTE_KIND (inner_link) != REG_DEP_OUTPUT
+ 		              &&*/ && (GET_CODE (temp_insn) == INSN
+ 		                  && next_nonnote_insn (temp_insn) ==
+ 		                  		ORG_NEXT_INSN (temp_insn))
+ 		              && RTX_IS_RISC_P (temp_insn)
+ 		              && GET_CODE (PATTERN (temp_insn)) == SET
+ 		              && GET_CODE (SET_DEST (PATTERN (temp_insn)))
+ 		                   == REG
+ 		              && (note
+ 		                   = find_regno_note (insn,
+ 		                                      REG_DEAD,
+ 		                       REGNO(SET_DEST (PATTERN (temp_insn)))))
+ 		              && rtx_equal_p (XEXP (note, 0),
+ 		                               SET_DEST (PATTERN (temp_insn)))
+ 		            )
+ 		            {
+ 		              try_combine (insn, XEXP (links, 0), temp_insn);
+ 		              three_insns = 1;
+ 		            }
+ 		        }
+ 		    }
+ 
+ 		  if (! three_insns)
+ 		    {
+ 		     /* intel2 - end */
+ 	             try_combine (insn, XEXP (links, 0), 0);
+ 	           }
+ 	        }
+ 	    }
+ 	}
+       if(GET_CODE (insn) == INSN ||
+          GET_CODE (insn) == CALL_INSN ||
+          GET_CODE (insn) == JUMP_INSN)
+ 	  record_dead_and_set_regs (insn);
+     }
+ 
+   in_recombine = 0;
+ 
+ }
+ 
+ 
+ 
+ /* intel2 - begin */
+ 
+ /* we will probably need this - check it and remvoe it if not... */
+ 
+ /*#include "hard-reg-set.h"*/
+ 
+ /* Set of registers that are free and ready to use at this moment.  */
+ 
+ HARD_REG_SET free_regs;
+ 
+ /* Set of registers that are not recommended for allocating at this moment.  */
+ 
+ static HARD_REG_SET not_recommended_regs;
+ 
+ typedef struct {
+   rtx mem;  /* mem rtx, this regno holds */
+   rtx insn_dead;  /* insn in which this regno dies */
+   rtx insn_load;  /* insn in which this regno is loaded */
+   rtx insn_store;  /* insn in which this regno is stored */
+ }  MEM_HOLDER;
+ 
+ /* Indexed by regno, indicates which register currently, holds a copy of
+    memory and the rtx represents this memory, as well as the insn loaded it,
+    and the insn in which this register was dead. */
+ 
+ MEM_HOLDER regno_holds_mem[FIRST_PSEUDO_REGISTER];
+ /* Perform simplification of memory accessed instructions by replacing them
+    with risc-like instructions.
+    FILE is a file to output debugging information on,
+    or zero if such output is not desired.  */
+ 
+ void
+ memory_simplify (file, f)
+      FILE *file;
+      rtx f;
+ {
+   register int block, j;
+   int regno, limit;
+   int i; /* intel1 */
+   int nregs; /* intel1 */
+   char * fmt; /* intel1 */
+   MEM_HOLDER *mhp;
+   rtx copy_reg = NULL;
+   rtx t_insn;
+ 
+   /* record which is the last register used for a spill reload */
+   static int last_load_reg;
+   /* Initialize reg_holds_mem */
+ 
+   bzero (regno_holds_mem, sizeof regno_holds_mem);
+     
+   /* since all registers now are hard registers, FIRST_PSEUDO_REGISTER is a
+      valid initialization value */
+ 
+   last_load_reg = FIRST_PSEUDO_REGISTER;
+ 
+   hard_reg_flow_analysis (f, file, 0 /* no pseudo registers' info. save */ );
+ 
+   if (n_basic_blocks <= 0)
+     {
+       return ;
+     }
+   /* To determine which registers are live after any insn, start from
+      the beginning of the basic block and scan insns, noting
+      which registers are set by each insn and which die there. */
+   for (block = 0; block < n_basic_blocks; block++)
+     {
+       register rtx insn;
+       int end_of_block_f;
+ 
+       if (file)
+ 	fprintf (file, "\nblock number: %d:\n", block);
+ 
+       last_load_reg = FIRST_PSEUDO_REGISTER;
+       /* since we cannot remove stores before a jump, we clean all the
+          insn_store data */
+ 
+       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ 	regno_holds_mem[regno].insn_store = 0;
+ 
+       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+         /* at the beginning of a block, each non-live hard register is
+ 	   considered free. */
+ 	{
+ 	  register int offset = regno / REGSET_ELT_BITS;
+ 	  register int bit = 1 << (regno % REGSET_ELT_BITS);
+ 	  if (basic_block_live_at_start[block][offset] & bit)
+ 	    CLEAR_HARD_REG_BIT (free_regs, regno);
+ 	  else
+ 	    SET_HARD_REG_BIT (free_regs, regno);
+         }
+ 
+       /* Traverse the block, an insn by insn, check for memory references,
+ 	 and find whether a risc-like insns instead are valid. If yes,
+ 	 replace the insn by another insn(s). */
+ 
+       end_of_block_f = 0;	/* signals the end of block reached */
+ 
+       for (insn = basic_block_head[block];
+ 	   !end_of_block_f;
+ 	   insn = NEXT_INSN (insn))
+ 	{
+ 	  rtx note, next, mem_opr = 0;
+ 	  rtx pat = PATTERN (insn);
+ 	  int regno, old_regno;
+ 	  int saved_code;
+ 
+ 	  /* try to eliminate as much stores as we can using the free_regs
+ 	     and regno_holds_mem information */
+ 
+ 	  if (GET_CODE (insn) == INSN
+ 	      && GET_CODE (pat) == SET
+ 	      && GET_CODE (SET_DEST (pat)) == MEM
+ 	      && GET_CODE (SET_SRC (pat)) == REG
+ 	      && GET_CODE (XEXP (SET_DEST (pat), 0)) != PRE_DEC
+ 	      && GET_CODE (XEXP (SET_DEST (pat), 0)) != PRE_INC
+ 	      && GET_CODE (XEXP (SET_DEST (pat), 0)) != POST_DEC
+ 	      && GET_CODE (XEXP (SET_DEST (pat), 0)) != POST_INC
+ 	      && (i = remove_redundant_store (SET_DEST (pat), block))
+ 	      && file)
+ 	    fprintf (file,
+ 	             "insn %d caused a deletion of a redundant store: %d\n",
+ 	                 INSN_UID (insn),
+ 	                 i);
+ 
+ 	  /* Try to eliminate as much loads as we can using the free_regs
+ 	     and regno_holds_mem information */
+ 
+ 	  else if (GET_CODE (insn) == INSN
+ 		   && GET_CODE (pat) == SET
+ 		   && (GET_CODE (SET_DEST (pat)) == REG
+ 		       || GET_CODE (SET_DEST (pat)) == MEM)
+ 		   && (GET_CODE (SET_SRC (pat)) == MEM
+ 		       || (GET_CODE (SET_SRC (pat)) == CONST_INT
+ 		           && flag_risc_const)))
+ 	    {
+ 	      int simple_copy_f = 0;
+ 	      rtx set_src = SET_SRC (pat);
+ 	      rtx set_dest = SET_DEST (pat);
+ 	      enum machine_mode mode = GET_MODE (set_dest);
+ 
+               if (GET_CODE (SET_DEST (pat)) == REG)
+ 	        old_regno = REGNO (set_dest);
+ 	      else
+ 	        old_regno = FIRST_PSEUDO_REGISTER;
+ 
+ 	      if (old_regno != FIRST_PSEUDO_REGISTER
+ 	          && (next = next_nonnote_insn (insn))
+       	          && GET_RTX_CLASS (GET_CODE (next)) == 'i'
+ 	          && ((note = find_regno_note (next, REG_DEAD, old_regno))
+ 	              ||
+ 	              (GET_CODE (PATTERN (next)) == SET && 
+ 	               rtx_equal_p (set_dest, SET_DEST (PATTERN (next)))))
+ 	          /* tevid */
+ 	          && (note == NULL 
+ 	              || mode == GET_MODE (XEXP (note, 0))))
+ 	        {
+ 		  rtx new_reg = NULL;
+ 	          rtx old_reg = set_dest; 
+ 	          int stop_replacement = 0;
+ 
+ 	          /* if this load is redundant (i.e. the memory loaded
+ 	             exists in any register, and the register we're loading
+ 	             to will die in the next insn), we can replace loaded
+ 	             register in the next insn with the already loaded register,
+ 	             and delete this insn.
+ 	          */
+ 	          if ((regno = find_regno_holds_mem (set_src, mode))
+ 	          	 				!= FIRST_PSEUDO_REGISTER
+ 		       && HARD_REGNO_NREGS (regno, mode) == 1
+ 		       && regno_holds_mem[regno].insn_load
+ #ifdef STACK_REGS
+ 		       && (STACK_REG_P (old_reg)
+ 			   || NON_STACK_REG_P (new_reg = gen_rtx (REG,
+ 			      	     mode,
+ 			      	     regno)))
+ 
+ #endif
+ 		       && TEST_HARD_REG_BIT (free_regs, regno))
+ 		    {
+ #ifdef STACK_REGS
+                       if (!new_reg)
+ 		        new_reg = gen_rtx (REG, mode, regno);
+ #endif
+ 
+ 		      /* replace this register in the next insn */
+                       init_undo_buf ();
+                       saved_code = INSN_CODE (next);
+ 		      subst_in_insn (next,
+ 		      		     PATTERN (next),
+ 		      		     old_reg,
+ 		      		     new_reg,
+ 		      		     0,
+ 		      		     0);
+ 		      if (note == NULL)
+ 		        { /* Then the dest of next must remain old_reg */
+ 		          SET_DEST (PATTERN (next)) = old_reg;
+ 		        }
+ 
+ #ifdef REGISTER_CONSTRAINTS
+ 
+ 	              INSN_CODE (next) = recog (PATTERN (next), next, 0);
+ 	              if (INSN_CODE (next) != -1)
+ 		        insn_extract (next);
+ 
+ 		      if (INSN_CODE (next) == -1
+ 		          || !constrain_operands (INSN_CODE (next), 1))
+ 		        {
+ 			  /* restore the previous situation */
+ 			  loop_undo_all();
+ 			  INSN_CODE (next) = saved_code;
+ 		          stop_replacement = 1;
+  		        }
+ #endif
+ 		      if (!stop_replacement)
+ 		        {
+ 			      
+ 			  if (regno != old_regno)
+ 			    {
+ 			      if (note != NULL)
+ 			        {
+ 			          /* The regno in the REG_DEAD note should be
+ 			             also changed */
+ 
+ 		                  XEXP (note, 0) = new_reg;
+ 		          
+ 		                  /* Now, if we replaced a REG_DEAD note, and
+ 		                     the new_reg is the destination of the next
+ 		                     insn, we should remove this note */
+ 
+ 		                  if (GET_CODE (SET_DEST (PATTERN (next)))
+ 		                       == REG
+ 			              && REGNO (SET_DEST (PATTERN (next)))
+ 			                   == regno)
+ 		                    remove_death (regno, next);
+ 		                }	  
+ 		              /* replace the registers in the free_register
+ 		                 list */
+ 
+ 		              nregs = HARD_REGNO_NREGS (old_regno, mode);
+ 		              for (i = 0; i < nregs; i++)
+ 		                SET_HARD_REG_BIT (free_regs, old_regno + i);
+ 		              nregs = HARD_REGNO_NREGS (regno, mode);
+ 		              for (i = 0; i < nregs; i++)
+ 		                CLEAR_HARD_REG_BIT (free_regs, regno + i);
+ 		            }  /* if (regno != old_regno) */
+ 		          else
+ 		          /* regno == old_regno */
+ 		            {
+ 		              /* mark that regno is not free anymore */
+ 		              nregs = HARD_REGNO_NREGS (regno, mode);
+ 		              for (i = 0; i < nregs; i++)
+ 		                CLEAR_HARD_REG_BIT (free_regs, regno + i);
+ 		            }
+ 
+ 		          /* now we can delete this insn ... */
+ 
+ 		          if (basic_block_head[block] == insn)
+ 		            basic_block_head[block] = NEXT_INSN (insn);
+ 
+ 			  mhp = &regno_holds_mem[regno];
+                           /* we should reset the RISC flag on the insns
+ 	                     added for risc, so that they will not be
+ 			     recombined later */
+ 
+ 			  
+ 			  if (mhp -> insn_dead)
+ 			    {
+ 			      t_insn = PREV_INSN (mhp->insn_dead);
+ 			      while (t_insn && RTX_IS_RISC_P (t_insn))
+ 			        {
+ 			          RTX_IS_RISC_P (t_insn) = 0;
+ 			          t_insn = PREV_INSN (t_insn);
+ 			        }
+ 			      remove_death (regno, mhp -> insn_dead);
+ 			      if (! t_insn)
+ 			        /* something went wrong */
+ 			        abort ();
+ 			    }
+ 
+ 		          if (file)
+ 		            fprintf (file,
+ 		                     "insn %d: deleted - redundant "
+ 		                     "load encountered (insn %d)\n",
+ 		                     INSN_UID (insn),
+ 		                     INSN_UID (mhp -> insn_load));
+ 		                
+ 			  PUT_CODE (insn, NOTE);
+ 		          NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 		          NOTE_SOURCE_FILE (insn) = 0;
+ 
+ 			  /* ... and start working on the next insn */
+ 
+ 		          continue;
+ 
+ 		 	}  /* if (!stop_replacement) */
+ 	              
+ 		    }  /* if ((regno = find_regno_holds_mem (set_src)) !=
+ 							   FIRST_PSEUDO_REGISTER
+ 			           && TEST_HARD_REG_BIT (free_regs, regno)) */
+ 	             
+ 		  else if (regno != FIRST_PSEUDO_REGISTER)
+ 		    /* regno holds the appropriate value but is not free, 
+ 		       so we can use its contents to
+ 		       convert this insn to a simple reg to reg copy */
+ 		    {
+ 		      copy_reg = gen_rtx (REG, mode, regno);
+ #ifdef STACK_REGS
+ 		      if (GET_CODE (SET_DEST (pat)) != REG
+ 		          || (STACK_REG_P (SET_DEST (pat))
+                               == STACK_REG_P (copy_reg)))
+ #endif
+                         {                  
+ 		          simple_copy_f = 1;
+ 		        }
+ 		    }
+ 
+ 	          else if (old_regno == last_load_reg
+ 			   && (regno =
+ 			        find_free_reg (GET_MODE (SET_DEST (pat)))) !=
+ 		               FIRST_PSEUDO_REGISTER
+ 		           && regno != old_regno)
+ 	            {
+ 		      new_reg = gen_rtx (REG, mode, regno);
+ 
+ 	              /* replace this insn's register with regno */
+ 
+ 	              SET_DEST (pat) = new_reg;
+ 
+ 		      /* replace this register in the next insn and its
+ 		         REG_NOTES */
+ 		      init_undo_buf ();
+ 		      saved_code = INSN_CODE (next);
+ 		      subst_in_insn (next,
+ 		    		     PATTERN (next),
+ 		    		     old_reg,
+ 		    		     new_reg,
+ 		    		     0,
+ 		    		     0);
+ 		      if (note == NULL)
+ 		       { /* Then the dest of next must remain old_reg */
+ 		         SET_DEST (PATTERN (next)) = old_reg;
+ 		       }
+ 
+ #ifdef REGISTER_CONSTRAINTS
+ 	              if ((INSN_CODE (next) = recog (PATTERN (next),
+ 							 next,
+ 							 0)) != -1)
+ 		        insn_extract (next);
+ 
+ 		      if (INSN_CODE (next) == -1
+ 		          || !constrain_operands (INSN_CODE (next), 1))
+ 		        {
+ 			  /* restore the previous situation */
+ 	                  SET_DEST (pat) = old_reg;
+ 	                  loop_undo_all ();
+ 		      	  INSN_CODE (next) = saved_code;
+ 		          stop_replacement = 1;
+  		        }
+ #endif
+ 		      if (!stop_replacement)
+ 		        {
+ 		          if (note != NULL)
+ 		            {
+ 			      /* The regno in the REG_DEAD note should be
+ 			         changed */
+ 
+ 		              XEXP (note, 0) = new_reg;
+ 		          
+ 		              /* Now, if we replaced a REG_DEAD note, and the
+ 		                 new_reg is the destination of the next insn, we
+ 		                 should remove this note */
+ 
+ 		              if (GET_CODE (SET_DEST (PATTERN (next))) == REG
+ 			          && REGNO (SET_DEST (PATTERN (next))) == regno)
+ 		                remove_death (regno, next);
+ 			    }
+ 		          /* replace the registers in the free_register
+ 		             list */
+ 
+ 		          nregs = HARD_REGNO_NREGS (regno, mode);
+ 		          for (i = 0; i < nregs; i++)
+ 		            CLEAR_HARD_REG_BIT (free_regs, regno + i);
+ 		          nregs = HARD_REGNO_NREGS (old_regno, mode);
+ 		          for (i = 0; i < nregs; i++)
+ 		            SET_HARD_REG_BIT (free_regs, old_regno + i);
+ 
+ 		          /* replace relevant data in regno_holds_mem */
+ 		          regno_holds_mem[regno].mem = set_src;
+ 		          regno_holds_mem[regno].insn_load = insn;
+ 		          regno_holds_mem[regno].insn_dead = next;
+ 
+ 		          if (file)
+ 		            fprintf (file, 
+ 		            "insn %d: replacing reload register %d with register %d\n",
+ 			    INSN_UID (insn), old_regno, regno);
+ 		 	}  /* if (!stop_replacement) */
+ 	              
+ 	            }  /* else if (old_regno == last_load_reg
+ 			       && (regno =
+ 				  find_free_reg (GET_MODE (set_dest))) !=
+ 							  FIRST_PSEUDO_REGISTER)
+ 			   */
+ 
+ 		  else if (old_regno == last_load_reg
+ 			   && file)
+ 		    fprintf (file,
+ 			     "insn %d: no free register found for reload."
+ 		             "\n", 
+ 			     INSN_UID (insn));
+ 
+ 	        }  /* if ((next = next_nonnote_insn (insn))
+       	                && GET_RTX_CLASS (GET_CODE (next)) == 'i'
+ 	                && (note = find_regno_note (next, REG_DEAD, old_regno)))
+ 	               */
+ 
+ 	      else if ((regno = find_regno_holds_mem (set_src, mode)) 
+ 	                != FIRST_PSEUDO_REGISTER
+ 		        && HARD_REGNO_NREGS (regno, mode) == 1)
+ 		{
+ 		  copy_reg = gen_rtx (REG, mode, regno);
+ #ifdef STACK_REGS
+ 		  if (GET_CODE (set_dest) != REG
+ 		      || (STACK_REG_P (set_dest) == STACK_REG_P (copy_reg)))
+ #endif
+                     simple_copy_f = 1;
+ 	        }
+ 
+ 	      if (simple_copy_f)
+ 		{
+ 		  MEM_HOLDER *mhp_org;
+ 		  rtx mem;
+ 		        
+ 		  /* we can change this insn to a simple reg copy, instead
+ 		     of a load or store */
+ 
+ 		  mem = SET_SRC (pat);
+ 		  if (copy_reg == NULL)
+ 		    {
+ 		      copy_reg = gen_rtx (REG, mode, regno);
+ 		    }
+ 
+ 		  saved_code = INSN_CODE (insn);
+ 		  SET_SRC (pat) = copy_reg;
+ 
+ #ifdef REGISTER_CONSTRAINTS
+ 	          if ((INSN_CODE (insn) = recog (PATTERN (insn),
+ 						 insn,
+ 						 0)) != -1)
+ 		    insn_extract (insn);
+ 
+ 		  if (INSN_CODE (insn) == -1
+ 		      || !constrain_operands (INSN_CODE (insn), 1))
+ 		    {
+ 		      SET_SRC (pat) = mem;
+ 		      INSN_CODE (insn) = saved_code;
+ 		    }
+ 		  else
+ 		    {
+ #endif
+ 
+ 		      /* now we should eliminate the possibility of the risc
+ 		         sequence loaded the memory int regno, to be later
+ 		         recombined */
+ 
+ 		      mhp_org = &regno_holds_mem[regno];
+ 		      mhp = &regno_holds_mem[old_regno];
+ 		      if (mhp_org -> insn_load)
+ 			{
+ 		          /* we should reset the RISC flag on the insns
+ 		             added for risc, so that they will not be
+ 		             recombined later */
+ 
+ 
+ 			  if (mhp_org -> insn_dead)
+ 			    {
+ 			      t_insn = PREV_INSN (mhp_org->insn_dead);
+ 			      while (t_insn  && RTX_IS_RISC_P (t_insn))
+ 			        {
+ 			          RTX_IS_RISC_P (t_insn) = 0;
+ 			          t_insn = PREV_INSN (t_insn);
+ 			        }
+ 			      if (! t_insn)
+ 			        fprintf (stderr,
+ 			                 "Not encountered insn_dead\n");
+ 			      remove_death (regno, mhp_org -> insn_dead);
+ 			    }
+ 			}  /* if (mhp_org -> insn_load) */
+ 
+ 		      /* we should update old_regno entries in
+ 			 regno_holds_mem array */
+ 
+ 		      mhp -> mem = mhp_org -> mem;
+ 		      mhp -> insn_load = insn;
+ 			  
+ 		      if (file)
+ 		        fprintf (file,
+ 		                 "insn %d: mem source replaced with reg\n",
+ 		                 INSN_UID (insn));
+ 
+ #ifdef REGISTER_CONSTRAINTS
+ 		    }  /* else of if (INSN_CODE (insn) == -1
+ 		                   || !constrain_operands (INSN_CODE (insn), 1))
+ 		       */
+ #endif
+ 		}  /* if (simple_copy_f) */
+ 
+               if (GET_CODE (pat) == SET 
+                   && GET_CODE (SET_DEST (pat)) == REG)
+ 	        last_load_reg = REGNO (SET_DEST (pat));
+ 
+ 	    }  /* if (GET_CODE (insn) == INSN
+ 	                  && GET_CODE (pat) == SET
+ 	                  && GET_CODE (SET_DEST (pat)) == REG
+ 	                  && GET_CODE (SET_SRC (pat)) == MEM) */
+ 
+ 	  /* mark all the original insns (those not created here). Since
+ 	     we use here the same bit as RTX_IS_SPILL_P, we should do this
+ 	     after checking for the spill reload register substitution. */
+ 	  RTX_IS_RISC_P (insn) = 0;
+ 
+ 	  end_of_block_f = (insn == basic_block_end[block]);
+ 	  if (!INSN_UID (insn))
+ 	    fatal ("\nMemory simplify: Scanning illegal insn.");
+ 
+ 	  if (GET_CODE (insn) == INSN)
+ 	    {
+ 	      register rtx note;
+ 
+ 	      if (GET_CODE (pat) == SET)
+ 		{
+ 		  rtx prev_insn, next_insn;
+ 		  rtx insn_src = SET_SRC (pat);
+ 		  rtx insn_dest = SET_DEST (pat);
+ 		  int mem_opr_is_src = 0;
+ 
+ 		  /* indicates which of the two SET_SRC's arguments is a
+ 		     memory reference. 0 - indicates the first one and 1 -
+ 		     the second */
+ 		         
+ 		  int mem_loc;
+ 
+ 		  switch (GET_CODE (insn_src))
+ 		    {
+ 		      case CONST_INT:
+ 		        if (flag_risc_const
+ 		            && GET_CODE (insn_dest) == MEM
+ 		            && !push_operand (insn_dest, 
+ 		                                 GET_MODE (insn_dest)))
+ 			  {
+ 			    mem_opr = insn_src;
+ 			    mem_loc = 1;
+                             mem_opr_is_src = 1;
+ 			    /* this is a trick to make the code replacing
+ 			       the memory operand in any other insn, valid
+ 			       even here.
+ 			       Note that insn_src now is actually the
+ 			       insn's pattern, and not the SET_SRC of it. */
+ 			    insn_src = pat;
+ 			  }
+                         break;
+ 		      case REG:
+ 		      case SYMBOL_REF:
+ 			/* do nothing, this is a simple copy */
+ 			break;
+ 		      case MEM:
+ 			if (GET_CODE (insn_dest) == CC0)
+ 			  /* this insn is not a simple load */
+ 			  {
+ 			    mem_opr = insn_src;
+ 			    mem_loc = 1;
+ 
+                             mem_opr_is_src = 1;
+ 			    /* this is a trick to make the code replacing
+ 			       the memory operand in any other insn, valid
+ 			       even here.
+ 			       Note that insn_src now is actually the
+ 			       insn's pattern, and not the SET_SRC of it. */
+ 			    insn_src = pat;
+ 			  }
+ 			break;
+ 		      default:
+ 		        if (GET_CODE (insn_src) == SIGN_EXTRACT
+ 		            || GET_CODE (insn_src) == ZERO_EXTRACT)
+ 		          { /* These cannot be handled properly */
+ 		            break;
+ 		          }
+ 			fmt = GET_RTX_FORMAT (GET_CODE (insn_src));
+ 			if (GET_CODE (XEXP (insn_src, 0)) == MEM)
+ 			  {
+ 			    mem_loc = 0;
+ 			    mem_opr = XEXP (insn_src, 0);
+ 			  }
+ 			else if (GET_RTX_LENGTH (GET_CODE (insn_src)) > 1
+ 				 && fmt[1] == 'e'
+ 				 && GET_CODE (XEXP (insn_src, 1)) == MEM)
+ 			  {
+ 			    mem_loc = 1;
+ 			    mem_opr = XEXP (insn_src, 1);
+ 			  }
+ 			break;
+ 		    }	/* switch (GET_CODE(insn_src)) */
+ 
+ 		  if (mem_opr)
+ 		    /* we found a memory operand that we should replace */
+ 		    {
+ 		      int skip_load_f = 0;  /* should we skip mem load? */
+ 		      int regno_is_free = 0; /* was it allocated by find_free_reg */
+ 		      int memory_dest_changed  
+ 			      		 = GET_CODE (insn_dest) == MEM
+ 			      		    && rtx_equal_p (insn_dest, mem_opr);
+ 		      enum machine_mode mode = GET_MODE (mem_opr);
+ 
+                       if (GET_CODE (mem_opr) == CONST_INT)
+                         mode = GET_MODE (insn_dest);
+ 		      if ((regno = find_regno_holds_mem (mem_opr, mode)) 
+ 		           != FIRST_PSEUDO_REGISTER)
+ 			{
+ 			  if (HARD_REGNO_NREGS (regno, mode) == 1
+ 			      && TEST_HARD_REG_BIT (free_regs, regno))
+ 			    skip_load_f = 1;
+ 			  else
+ 			    regno = FIRST_PSEUDO_REGISTER;
+ 			}
+                       if (regno == FIRST_PSEUDO_REGISTER
+ #ifdef IS_RISC_MODE
+ 		          && (IS_RISC_MODE (GET_MODE (mem_opr))
+ 		              || GET_CODE (mem_opr) == CONST_INT)
+ #endif
+                          )
+                         { /* Look forward a few insns to see
+                              if this mem_opr will be loaded
+                              into a register and if it is then
+                              try to use that register for riscifying.  */
+                           t_insn = next_nonnote_insn (insn);
+                           while (t_insn && regno == FIRST_PSEUDO_REGISTER)
+                             {
+                               if (GET_CODE (t_insn) == CODE_LABEL
+                                   || GET_CODE (t_insn) == CALL_INSN)
+                                 {
+                                   break;
+                                 }
+                               if (GET_CODE (t_insn) == INSN)
+                                 {
+                                   register rtx dest;
+                                   
+                                   if (GET_CODE (PATTERN (t_insn)) != SET)
+                                     {
+                                       break;
+                                     }
+                                   dest = SET_DEST (PATTERN (t_insn));
+                                   if (GET_CODE (dest) == REG
+                                       && rtx_equal_p (mem_opr,
+                                           SET_SRC (PATTERN (t_insn))))
+                                     {
+                                       regno = REGNO (dest);
+ 			              nregs = HARD_REGNO_NREGS (regno, mode);
+ 			              if (HARD_REGNO_MODE_OK (regno, mode))
+ 			                {
+ 			                  for (i = 0; i < nregs; i++)
+ 			                    if (! TEST_HARD_REG_BIT (free_regs,
+ 			            			          regno + i))
+ 			                      {
+ 			                        regno = FIRST_PSEUDO_REGISTER;
+ 			                        break;
+ 			                      }
+ 			                }
+ 			              else
+ 			                regno = FIRST_PSEUDO_REGISTER;
+                                     }
+                                   else if (GET_CODE (dest) == MEM
+                                            && ! push_operand (dest,
+                                            		      GET_MODE (dest)))
+                                     /* since there is a write to memory, no use
+                                        in trying to load something that might be
+                                        clobbered. */
+ 			            regno = FIRST_PSEUDO_REGISTER;
+                                 }
+                               t_insn = next_nonnote_insn (t_insn);
+                             }
+                                      
+                         }
+                       if (regno == FIRST_PSEUDO_REGISTER
+ 			  && GET_CODE (insn_dest) == REG
+ #ifdef IS_RISC_MODE
+ 		          && (IS_RISC_MODE (GET_MODE (mem_opr))
+ 		              || GET_CODE (mem_opr) == CONST_INT)
+ #endif
+                          )
+ 			{
+ 			  regno = REGNO (insn_dest);
+ 			  nregs = HARD_REGNO_NREGS (regno, mode);
+ 
+ 			  if (HARD_REGNO_MODE_OK (regno, mode))
+ 			    {
+ 			      for (i = 0; i < nregs; i++)
+ 			        if (! TEST_HARD_REG_BIT (free_regs,
+ 			        			 regno + i))
+ 			          {
+ 			            regno = FIRST_PSEUDO_REGISTER;
+ 			            break;
+ 			          }
+ 			    }
+ 			  else
+ 			    regno = FIRST_PSEUDO_REGISTER;
+ 			}
+ 
+ 	              if (regno == FIRST_PSEUDO_REGISTER
+ #ifdef IS_RISC_MODE
+ 		          && (IS_RISC_MODE (GET_MODE (mem_opr))
+ 		              || GET_CODE (mem_opr) == CONST_INT)
+ #endif
+                          )
+ 			{
+ 			  prev_insn = prev_nonnote_insn (insn);
+ 			  next_insn = next_nonnote_insn (insn);
+ 
+ 			  /* update set of not recommended hard registers
+ 			     for find_free_reg () */
+ 			  /* NOTE that we can refer only to integer
+ 			     registers, but now we do it more general. */
+ 
+ 			  for (regno = 0;
+ 			       regno < FIRST_PSEUDO_REGISTER;
+ 			       regno++)
+ 
+ 			    if ((prev_insn
+ 			         && GET_RTX_CLASS (GET_CODE (prev_insn))
+ 						  == 'i'
+ 			         && (INSN_USES_REGNO (prev_insn, regno)
+ 				     || INSN_SETS_REGNO (prev_insn, regno)))
+ 				     || (next_insn
+ 				        && GET_RTX_CLASS (GET_CODE (next_insn))
+ 									  == 'i'
+ 				 && (INSN_USES_REGNO (next_insn, regno)
+ 			         /* If the destination is MEM we
+ 			            might write the new register
+ 			            contents to the memory as the
+ 			            last insn. This will force us to
+ 			            also consider a write to the
+ 			            allocated register in the next
+ 			            insn. */
+ 
+ 				  || (memory_dest_changed
+ 				      && INSN_SETS_REGNO (next_insn,
+ 				                          regno)))))
+ 			      SET_HARD_REG_BIT (not_recommended_regs,regno);
+ 			    else
+ 			      CLEAR_HARD_REG_BIT (not_recommended_regs,
+ 			      		      regno);
+ 
+ 			  regno = find_free_reg (mode);
+ 			  regno_is_free = 1;
+ 			}
+ 
+ 	              if (regno != FIRST_PSEUDO_REGISTER)
+ 			{
+ 			  rtx new_insn, new_reg, link;
+ 
+ 			  /* before changing the insn, and adding others, we
+ 			     check the changed insn will be legal. */
+ 
+ 			  new_reg = gen_rtx (REG, mode, regno);
+ 			  saved_code = INSN_CODE (insn);
+ 			  if (mem_opr_is_src)
+ 			    {
+ 			      SET_SRC (pat) = new_reg;
+ 			    }
+ 			  else
+ 			    {
+                               init_undo_buf ();
+ 			      subst_in_insn (insn, pat, mem_opr, new_reg, 0, 0);
+ 			    }
+ 			      
+ #ifdef REGISTER_CONSTRAINTS
+ 			  /* now check if the insn's O.K. */
+ 
+ 			  INSN_CODE (insn) = recog (pat, insn, 0);
+ 
+ 			  if (INSN_CODE (insn) != -1)
+ 			    insn_extract (insn);
+ 
+ 			  if (INSN_CODE (insn) == -1
+ 			      || ! constrain_operands (INSN_CODE (insn), 1))
+ 		            {
+ 			      if (mem_opr_is_src)
+ 			        {
+ 			          SET_SRC (pat) = mem_opr;
+ 			        }
+ 			      else
+ 			        {
+ 			          loop_undo_all ();
+ 			        }
+ 			      INSN_CODE (insn) = saved_code;
+ 			    }
+ 			  else  /* the replacement is valid */
+ 			    {
+ #endif
+ 			      if (! skip_load_f)
+ 			        {
+ 
+ 			          if (mode != SImode && regno_is_free
+ 			              && GET_CODE (mem_opr) == CONST_INT)
+ 			            {
+ 			              new_reg = gen_rtx (REG, SImode, regno);
+ 			            }
+ 			          /* load the memory into regno */
+ 			          new_insn 
+ 			           = make_insn_raw (gen_rtx (SET,
+ 							     VOIDmode,
+ 							     new_reg,
+ 							      mem_opr));
+ 
+ 				  RTX_IS_RISC_P (new_insn) = 1;
+ 			          add_insn_after (new_insn,
+ 						  PREV_INSN (insn));
+ 
+ 				  /* record regno as the last register that
+ 				    is used for loading */
+ 			      
+ 				  last_load_reg = regno;
+ 
+ 
+ 				  /* update new data in regno_holds_mem[] */
+ 				      
+ #if 0
+ 				  mhp = &regno_holds_mem[regno];
+ 				  mhp -> insn_load = new_insn;
+ #endif
+ 				  update_regno_holds_mem(new_insn,
+ 				    	     PATTERN(new_insn));
+ 				      
+ 				  /* if insn was the first insn in this
+ 				     block this should be updated */
+ 
+ 				  if (basic_block_head[block] == insn)
+ 				    basic_block_head[block] = new_insn;
+ 
+ 				  if (file)
+ 				    {
+ 					fprintf (file, "insn %d was added ",
+ 						   INSN_UID (new_insn));
+ 					fprintf (file, "before insn %d\n",
+ 						       INSN_UID (insn));
+ 				    }
+ 
+ 				  /* move the insn's LOG_LINKS to new_insn */
+ 				  LOG_LINKS (new_insn) = LOG_LINKS (insn);
+ 				  LOG_LINKS (insn) = 0;
+ 
+ 				  /* move all relevant REG_DEAD notes to
+ 				     new_insn */
+ 				  for (note = REG_NOTES (insn);
+ 				       note;
+ 				       note = XEXP (note, 1))
+ 				    {
+ 				      if (REG_NOTE_KIND (note) == REG_DEAD)
+ 					{
+ 					  register int regno 
+ 					    = REGNO (XEXP (note, 0));
+ 
+ 					  if (GET_RTX_LENGTH (
+ 					  	GET_CODE (insn_src)) < 2
+ 					        || GET_CODE (XEXP (insn_src,
+ 					      	     1 - mem_loc))
+ 					      	     != REG
+ 					       || REGNO (XEXP (insn_src,
+ 							 1 - mem_loc))
+ 							!= regno)
+ 					    {
+ 					          
+ 					      /* this note does not refer to
+ 					         the register that will be
+ 					         used from now on within
+ 					         insn, thus we move it to
+ 					        new_insn. */
+ 
+ 					      remove_note (insn, note);
+ 					      mhp = &regno_holds_mem[regno];
+ 					      REG_NOTES (new_insn) =
+ 					      gen_rtx (EXPR_LIST,
+ 							REG_DEAD,
+ 							XEXP (note, 0),
+ 							REG_NOTES(new_insn));
+ 					      mhp -> insn_dead = new_insn;
+ 
+ 					      SET_HARD_REG_BIT
+ 						       (free_regs,
+ 						        REGNO (XEXP (note, 0)));
+ 					    }
+ 					}  /* if (REG_NOTE_KIND (note) == REG_DEAD) */
+ 				    }  /* for (note = REG_NOTES (insn);
+ 					           note;
+ 					           note = XEXP (note, 1)) */
+ 				}  /* if (! skip_load_f) */
+ 		              else
+ 				/* we use an already loaded register */
+ 				{
+ 
+ 				  /* since we use a load for a possibly 
+ 				     previously riscified insn, we should
+ 				     unmark the insns created for that insn,
+ 				     so that recombine will not try to
+ 				     delete its load */
+ 				  mhp = &regno_holds_mem[regno];
+ 				  if (mhp -> insn_dead)
+ 				    {
+ 				      /* we should reset the RISC flag on
+ 				         the insns added for risc, so that
+ 				         they will not be recombined later
+ 				      */
+ 
+ 				      t_insn = PREV_INSN (mhp -> insn_dead);
+ 				      while (t_insn && RTX_IS_RISC_P (t_insn))
+ 					{
+ 					   RTX_IS_RISC_P (t_insn) = 0;
+ 					   t_insn = PREV_INSN (t_insn);
+ 					}
+ 			              remove_death (regno, mhp->insn_dead);
+ 			            }  /* if (mhp -> insn_load) */
+ 
+ 				  if (file)
+ 				    {
+ 				      fprintf (file, "insn %d: changed mem ",
+ 							   INSN_UID (insn));
+ 				      fprintf (file, "operand with already "
+ 							   "loaded register %d\n",
+ 							   regno);
+ 				    }
+ 				}
+ 
+ 		              /* in the case the memory operand was also the
+ 				 insn's destination, we should add an insn
+ 				 to store the result, now stored in
+ 				 new_reg. */
+ 
+ 		              if (memory_dest_changed)
+ 			        {
+ 			          /* Since memory destination was replaced by
+ 			             a register, its contents is clobbered */
+ 
+ #if 0
+ 				  regno_holds_mem[regno].mem = 0;
+ #endif
+ 				  bzero (&regno_holds_mem[regno],
+ 				         sizeof (MEM_HOLDER));
+ 				  update_entries (new_reg);
+ 
+ 				  new_insn = make_insn_raw (pat);
+ 
+ 				  RTX_IS_RISC_P (new_insn) = 1;
+ 				  add_insn_after (new_insn,
+ 					          PREV_INSN (insn));
+ 
+ 				  if (skip_load_f
+ 				      && basic_block_head[block] == insn)
+ 				    basic_block_head[block] = new_insn;
+ 
+ 				  if (file
+ 				      && ! skip_load_f)
+ 				    {
+ 				      fprintf (file, "insn %d was also ",
+ 					       INSN_UID (new_insn));
+ 				      fprintf (file, "added before insn ");
+ 				      fprintf (file, "%d\n",
+ 					  		INSN_UID (insn));
+ 				    }
+ 				  else if (file)
+ 				    {
+ 				    fprintf (file,
+ 				             "insn %d was added before "
+ 				             "insn %d, load was saved\n",
+ 				             INSN_UID (new_insn),
+ 				             INSN_UID (insn));
+ 				   }
+ 
+ 
+ 				  /* change insn to be just a store insn */
+ 				  PATTERN (insn) = gen_rtx (SET,
+ 								VOIDmode,
+ 								mem_opr,
+ 								new_reg);
+ 
+ 				  /* now we might find that a previous
+ 				     store is redundant... */
+ 				  if ((i = remove_redundant_store (mem_opr,
+ 								   block))
+ 				       && file)
+ 				    {
+ 				    fprintf (file,
+ 				             "insn %d: caused deletion of "
+ 				             "a redundant store: %d\n",
+ 				             INSN_UID (insn),
+ 				             i);
+ 				    }
+ 
+ 				  /* now we actually changed the insn's
+ 				     code, so we erase the current one and
+ 				     we let next phases (probably sched2) to
+ 				     update this code. */
+ 
+ 				  INSN_CODE (insn) = -1;
+ 
+ 				  if (! skip_load_f)
+ 				    {
+ 				      /* add the last_new_insn to the new_insn's
+ 					 dependency list */
+ 
+ 				      link = rtx_alloc (INSN_LIST);
+ 				      PUT_REG_NOTE_KIND (link, 0);
+ 				      XEXP (link, 0) = PREV_INSN (new_insn);
+ 				      XEXP (link, 1) = LOG_LINKS (new_insn);
+ 				      LOG_LINKS (new_insn) = link;
+ 				    }
+ 				}	/* if (memory_dest_changed) */
+ 
+ 		              /* add the new_insn to the insn's dependency
+ 				 list */
+ 
+ 		              if (! skip_load_f
+ 				  || memory_dest_changed)
+ 				{
+ 				  link = rtx_alloc (INSN_LIST);
+ 				  PUT_REG_NOTE_KIND (link, 0);
+ 				  XEXP (link, 0) = new_insn;
+ 				  XEXP (link, 1) = LOG_LINKS (insn);
+ 				  LOG_LINKS (insn) = link;
+ 				}
+ 
+ 				  /* Add a REG_DEAD note to the last insn to
+ 				     indicate that the used register is no
+ 				     longer needed.
+ 				     This is not needed for this phase since we
+ 				     do not remove this register from the free
+ 				     register list (we just mark it to indicate
+ 				     that next allocation of free register, will
+ 				     not return it again, so that dependency
+ 				     between adjacent insns will be as less as
+ 				     possible). */
+ 
+ 			      if (GET_CODE (insn_dest) != REG
+ 				  || REGNO (insn_dest) != REGNO (new_reg))
+ 		              {
+ 				REG_NOTES (insn) 
+ 				  = gen_rtx (EXPR_LIST,
+ 					     REG_DEAD,
+ 					     new_reg, 
+ 					     REG_NOTES (insn));
+ 		              }
+ #ifdef REGISTER_CONSTRAINTS
+ 		            }  /* the replacement is valid */
+ #endif
+ 			}  /* if (regno != FIRST_PSEUDO_REGISTER) */
+ 		      else if (file)
+ 			{
+ 			        fprintf (file, "insn %d: No suitable free hard",
+ 			      				       INSN_UID (insn));
+ 			        fprintf (file, " register found for risc\n");
+ 			}
+ 		    }  /* if (mem_opr) */
+ 		}  /* if (GET_CODE (pat) == SET) */
+             }  /* if (GET_CODE(insn) == INSN) */
+ 
+ 	  if (GET_CODE (insn) == CODE_LABEL)
+ 	    bzero (regno_holds_mem, sizeof regno_holds_mem);
+ 
+ 	  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ 	    {
+ 
+ 	      if (GET_CODE (insn) == CALL_INSN)
+ 	        {
+ 		   /* all call clobbered registers are now free */
+ 
+ 		   for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ 		     if (call_used_regs[j])
+ 		          SET_HARD_REG_BIT (free_regs, j);
+ 	        }
+ 
+ 	      update_free_regs (PATTERN (insn));
+ 
+ 	      update_regno_holds_mem (insn, PATTERN (insn));
+ 
+ 	      /* add each dead register to the free_regs set */
+ 	      /* mark each dead regno in the regno_holds_mem array */
+ 	      for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ 	        {
+ 		  if ((REG_NOTE_KIND (note) == REG_DEAD
+ 		       || REG_NOTE_KIND (note) == REG_UNUSED)
+ 		      && GET_CODE (XEXP (note, 0)) == REG)
+ 		    {
+ 		      regno = REGNO (XEXP (note, 0));
+ 		      nregs = 
+ 		        HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
+   
+ 		      for (i = 0; i < nregs; i++)
+ 		        SET_HARD_REG_BIT (free_regs, regno + i);
+ 		      regno_holds_mem[regno].insn_dead = insn;
+ 		    }
+ 		}
+ 	      if ((note = find_reg_note (insn, REG_WAS_0, 0)))
+ 	        {
+ 	          rtx set;
+ 	          set = single_set (insn);
+ 	          if (set == NULL 
+ 		      || GET_CODE (SET_DEST (set)) == REG)
+ 	            { /* Since reg may have been reused.  */
+ 		      remove_note (insn, note);
+ 	            }
+ 	        }
+ 	    }  /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') */
+ 	}  /* for (insn = basic_block_head[block]; */
+     }  /* for (block = 0; block < n_basic_blocks; block++) */
+ 
+     /* mark each insn with it's next nonnote insn so that recombine can work */
+     {
+ 
+       t_insn = f;
+       while (t_insn)
+         {
+           if (GET_CODE (t_insn) == INSN)
+             ORG_NEXT_INSN (t_insn) = next_nonnote_insn (t_insn);
+           t_insn = NEXT_INSN (t_insn);
+         }
+     }
+ }				/* memory_simplify (file, f) */
+ 
+ 
+ static void
+ dump_free_registers (file)
+      FILE *file;
+ {
+   register int regno;
+ 
+   fprintf (file, "Free registers now are: ");
+   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+     if (TEST_HARD_REG_BIT (free_regs, regno))
+       {
+ 	fprintf (file, " %d", regno);
+       }
+   fprintf (file, "\n");
+ }
+ 
+ /*  Finds a free register that is able to contain a value of mode MODE.
+  *  Returns the number of the hard register (or the first hard register, in
+  *  case of multi-register value) found, if such exists, and mark it in the
+  *  regs_ever_live array. Otherwise returns  FIRST_PSEUDO_REGISTER.
+  */
+ 
+ int
+ find_free_reg (mode)
+      enum machine_mode mode;
+ {
+   register int regno;
+ 
+   /* record last_reg retunrned. Try next find form this reg on. */
+   static int last_reg;
+ 
+   int not_desired;		/* is this the "not-desired" regset: i.e. are we going to
+             * take the register from those who are not "safe" within
+             * a function (their values is promised not to be altered).
+             */
+   int second_half;		/* is this the second half of the "round-robin" search */
+ 
+ #ifdef IS_RISC_MODE
+   if (!IS_RISC_MODE (mode))
+     {
+       return (FIRST_PSEUDO_REGISTER);
+     }
+ #endif
+   /* we handle only DImode SImode, HImode and QImode */
+   switch (mode)
+     {
+     case DImode:
+     case SImode:
+     case HImode:
+     case QImode:
+ 
+       /* Try to find the register among those whos value is not "safe"
+        * first.
+        */
+       for (not_desired = 0; not_desired < 2; not_desired++)
+ 	{
+ 	  int last_reg_scanned = 0;
+ 
+ 	  /* implement a "round-robin" algorithm for register scanning.
+ 	     fisrt look from the last_reg and on, and then from 0 to
+ 	     last_reg. */
+ 	     
+ 	  for (regno = (last_reg + 1) % FIRST_PSEUDO_REGISTER;
+ 	       ! last_reg_scanned;
+ 	       regno = (regno + 1) % FIRST_PSEUDO_REGISTER)
+ 	    {
+ 	      register int i, nregs = HARD_REGNO_NREGS (regno, mode);
+ 	      register int found = 1;
+ 
+ 	      last_reg_scanned = last_reg == regno;
+ 	      for (i = 0; i < nregs; i++)
+ 	        {
+ 	          if (! not_desired
+ 		      && (! call_used_regs[regno + i]
+ 			  || TEST_HARD_REG_BIT (not_recommended_regs,
+ 			  			regno + i)))
+ 		    found = 0;
+ 	          else if (! fixed_regs[regno + i]
+ 	            	   && TEST_HARD_REG_BIT (free_regs, regno + i)
+ 	            	   && HARD_REGNO_MODE_OK (regno + i, mode)
+ #ifdef ELIMINABLE_REGS
+ 			   && (! frame_pointer_needed
+ 			       || regno != FRAME_POINTER_REGNUM)
+ #endif
+ 			   /* allow only registers that lived before this
+ 			      phase to take part. This might reduce the number
+ 			      of registers available, but otherwise some
+ 			      problems may occur due to use of a register that
+ 			      need to be pushed at the the function prologue,
+ 			      thus corrupting the calculations of stack slots
+ 			      previously performed at the reload phase. */
+ 			   && (call_used_regs[regno + i]
+ 			       || regs_ever_live[regno + i])
+ 			  )
+ 		    continue;
+ 		  else
+ 			found = 0;
+ 		}  /* for (i = 0; i < nregs; i++) */
+ 	      if (found)
+ 		{
+ 		  /* save regno for the next invokation */
+ 		  last_reg = regno + nregs - 1;
+ 
+ 		  return (regno);
+ 		}
+ 	    } /* for (regno = (last_reg + 1) % FIRST_PSEUDO_REG;
+ 	         regno != last_reg;
+ 	         regno = (regno + 1) % FIRST_PSEUDO_REG) */
+ 	}  /* for (not_desired = 0; not_desired < 2; not_desired ++) */
+       break;
+     }  /* switch (mode) */
+   return (FIRST_PSEUDO_REGISTER);
+ }
+ 
+ /* Updates the free_regs regset according the contents of PAT */
+ 
+ void
+ update_free_regs (rtx pat)
+ {
+   register int i, regno, nregs;
+   register j;
+   register char *fmt;
+   register RTX_CODE code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+       case SET:
+       case USE:
+       case CLOBBER:
+         if (GET_CODE (SET_DEST (pat)) == REG)
+           {
+             regno = REGNO (SET_DEST (pat));
+             nregs = HARD_REGNO_NREGS (regno,
+             					   GET_MODE (SET_DEST (pat)));
+ 
+             if (GET_CODE (pat) == SET
+                 || GET_CODE (pat) == USE)
+               for (i = 0; i < nregs; i++)
+                 CLEAR_HARD_REG_BIT (free_regs, regno + i);
+ #if 0
+             else /* GET_CODE (pat) == CLOBBER */
+               for (i = 0; i < nregs; i++)
+                 SET_HARD_REG_BIT (free_regs, regno + i);
+ #endif
+           }
+         else if (GET_CODE (SET_DEST (pat)) == SUBREG
+                  && GET_CODE (SUBREG_REG (SET_DEST (pat))) == REG)
+           {
+             regno = REGNO (SUBREG_REG (SET_DEST (pat))) 
+                          + SUBREG_WORD (SET_DEST (pat));
+             nregs = HARD_REGNO_NREGS (regno,
+             					   GET_MODE (SET_DEST (pat)));
+ 
+             if (GET_CODE (pat) == SET
+                 || GET_CODE (pat) == USE)
+               for (i = 0; i < nregs; i++)
+                 CLEAR_HARD_REG_BIT (free_regs, regno + i);
+           }
+         break;
+       case ADDR_VEC:
+       case CALL:
+       case HIGH:
+       case CONST_INT:
+       case CONST:
+       case CONST_DOUBLE:
+       case SYMBOL_REF:
+       case LABEL_REF:
+       case PC:
+       case CC0:
+       case REG:
+         /* do nothing */
+         return;
+    }  /* switch (GET_CODE (pat)) */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if( XEXP (pat, i))
+           update_free_regs (XEXP (pat, i));
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  update_free_regs (XVECEXP (pat, i, j));
+       }
+ }
+ 
+ #if 0
+ /* Returns a hard register regno, if the contents of entry regno in
+    last_reloads array equals to MEM, FIRST_PSEUDO_REGISTER otherwise. */
+ 
+ static int
+ find_last_reload (rtx mem)
+ {
+   register int regno;
+   
+   if (GET_CODE (mem) != MEM)
+     abort ();
+ 
+   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+     if (rtx_equal_p (LAST_RELOAD (regno), mem))
+       return (regno);
+ 
+   return (FIRST_PSEUDO_REGISTER);
+ }
+ #endif
+ 
+ /* Returns regno of a free register holding MEM, or FIRST_PSEUDO_REGISTER if
+    not exist such register. */
+ 
+ static int
+ find_regno_holds_mem (rtx mem, enum machine_mode mode)
+ {
+   int i, is_const;
+   MEM_HOLDER *mhp;
+ 
+   is_const = GET_CODE (mem) == CONST_INT;
+   
+   for (mhp = regno_holds_mem;
+        mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER;
+        mhp++)
+     {
+       if (mhp->mem && GET_CODE (mhp->insn_load) == NOTE)
+         { /* was deleted */
+           mhp->insn_load = NULL;
+           mhp->mem = NULL;
+           mhp->insn_dead = NULL;
+         }
+       if (mhp->insn_store && GET_CODE (mhp->insn_store) == NOTE)
+         { /* was deleted */
+           mhp->insn_store = NULL;
+         }
+ #if 0
+       if ((mhp->insn_load 
+            && mhp->mem
+ #endif
+       if ((mhp->mem
+            && GET_CODE (mhp -> mem) == GET_CODE (mem)
+            && (is_const 
+                 ? rtx_equal_p ( (mhp -> mem), (mem))
+                 : rtx_equal_p (XEXP (mhp -> mem, 0), XEXP (mem, 0)))
+            && HARD_REGNO_MODE_OK (mhp - regno_holds_mem, mode)
+            && GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (mhp -> insn_load))))
+                >= GET_MODE_SIZE (mode))
+ 	  || (mhp -> mem
+ 	      && mhp -> insn_store
+               && GET_MODE_SIZE (GET_MODE (SET_SRC (PATTERN (mhp -> insn_store))))
+                    >= GET_MODE_SIZE (mode)
+               && GET_CODE (SET_DEST ( PATTERN (mhp -> insn_store))) 
+                    == GET_CODE (mem)
+               && HARD_REGNO_MODE_OK (mhp - regno_holds_mem, mode)
+               && (is_const
+                   ? rtx_equal_p (SET_DEST ( PATTERN (mhp -> insn_store)), 
+                                  mem)
+                   : rtx_equal_p (XEXP (SET_DEST (PATTERN (mhp -> insn_store)),
+                   		       0),
+                                  XEXP (mem, 0)))))
+         return (mhp - regno_holds_mem);
+     }
+   return FIRST_PSEUDO_REGISTER;
+ }  /* find_regno_holds_mem (rtx mem) */
+ 
+ 
+ 
+ /* Updates the regno_holds_mem array as required from pat */
+ 
+ static void
+ update_regno_holds_mem (rtx insn, rtx pat)
+ {
+   register int i, j, regno, nregs;
+   MEM_HOLDER *mhp;
+   rtx set_src, set_dest;
+   register char *fmt;
+   register RTX_CODE code = GET_CODE (pat);
+ 
+   if (GET_CODE (insn) == JUMP_INSN)
+     {
+       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+         regno_holds_mem[i].insn_store = 0;
+       return;
+     }
+ 
+   switch (GET_CODE (pat))
+     {
+       case SET:
+         set_src = SET_SRC (pat);
+         set_dest = SET_DEST (pat);
+         if (GET_CODE (set_dest) == REG)
+           {
+             regno = REGNO (set_dest);
+             nregs = HARD_REGNO_NREGS (regno, GET_MODE (set_dest));
+ 
+             mhp = &regno_holds_mem[regno];
+             if (nregs == 1
+                 && (GET_CODE (set_src) == MEM
+                     && !MEM_VOLATILE_P (set_src)
+                     && GET_CODE (XEXP (set_src, 0)) != PRE_INC
+                     && GET_CODE (XEXP (set_src, 0)) != PRE_DEC
+                     && GET_CODE (XEXP (set_src, 0)) != POST_INC
+                     && GET_CODE (XEXP (set_src, 0)) != POST_DEC)
+                    || GET_CODE (set_src) == CONST_INT)
+               {
+                 mhp -> mem = set_src;
+                 mhp -> insn_load = insn;
+                 mhp -> insn_store = mhp -> insn_dead = 0;
+               }
+             else
+               {
+                 for (; mhp < &regno_holds_mem[regno] + nregs; mhp++)
+                   {
+                     bzero (mhp, sizeof (MEM_HOLDER));
+                   }
+               }
+             if (nregs == 1)
+               {
+                 /* since we set a register, each mem using this reg is not valid
+                    any more */
+ 
+                 update_entries (set_dest);
+               }
+             else
+               {
+                 /* memory holds more than one register. This is a simplification
+                    Actually we should zero only those register entries which are
+                    relevant for nregs... */
+                 bzero (regno_holds_mem, sizeof regno_holds_mem);
+                 break;
+               }
+             update_regno_holds_mem (insn, set_src);
+           }
+         else if (GET_CODE (set_dest) == SUBREG)
+           {
+             if (GET_CODE (SUBREG_REG (set_dest)) == REG)
+               {
+                 regno = REGNO (SUBREG_REG (set_dest)) + SUBREG_WORD (set_dest);
+                 nregs 
+                   = HARD_REGNO_NREGS (regno, GET_MODE (SUBREG_REG (set_dest)));
+ 
+                 mhp = &regno_holds_mem[regno];
+                 for (; mhp < &regno_holds_mem[regno] + nregs; mhp++)
+                   {
+                     bzero (mhp, sizeof (MEM_HOLDER));
+                   }
+                 if (nregs == 1)
+                   {
+                     update_entries (SUBREG_REG (set_dest));
+                   }
+                 else
+                   {
+                     /* memory holds more than one register. This is a simplification.
+                        Actually we should zero only those register entries which are
+                        relevant for nregs... */
+                     bzero (regno_holds_mem, sizeof regno_holds_mem);
+                   }
+                 update_regno_holds_mem (insn, set_src);
+                 return;
+               }
+             else /* subreg of mem */
+               {
+ 	        for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	          regno_holds_mem[i].mem = 0;
+                 update_regno_holds_mem (insn, XEXP (XEXP (set_dest, 0), 0));
+                 update_regno_holds_mem (insn, set_src);
+                 return;
+               }
+           }
+         else if (GET_CODE (set_dest) == MEM)
+           {
+ 	    MEM_HOLDER save_mh;
+ 	    int is_push = 0;
+ 
+ 	    mhp = 0;
+ 
+             if ((GET_CODE (set_src) == REG
+                  || GET_CODE (set_src) == CONST_INT)
+                 && push_operand (set_dest, Pmode))
+               { /* A push only ruins memory references based on stack_pointer */
+                 is_push = 1;
+               }
+             else if (GET_CODE (set_src) == REG
+                 /* We might want to add the possibility of SUBREG, isn't it? */
+                 && !MEM_VOLATILE_P (set_dest)
+                 && GET_CODE (XEXP (set_dest, 0)) != PRE_INC
+                 && GET_CODE (XEXP (set_dest, 0)) != PRE_DEC
+                 && GET_CODE (XEXP (set_dest, 0)) != POST_INC
+                 && GET_CODE (XEXP (set_dest, 0)) != POST_DEC)
+               {
+                 register int regno = REGNO (set_src);
+                 register int nregs = HARD_REGNO_NREGS (regno,
+                 				       GET_MODE (set_src));
+ 
+                 if (nregs == 1)
+                   {
+                     mhp = &regno_holds_mem[regno];
+                     save_mh = *mhp;
+                   }
+               }
+             else if (GET_CODE (set_src) != REG)
+               update_regno_holds_mem (insn, set_src);
+ 
+             if (!is_push)
+               {
+                 MEM_HOLDER *p = regno_holds_mem;
+                 rtx store_pat;
+                 
+ 	        for (; p < regno_holds_mem + FIRST_PSEUDO_REGISTER; p++)
+ 	          {
+ 	            if (p -> mem)
+ 	              {
+ 	                if (GET_CODE (p -> mem) == MEM
+ 	                    && true_dependence (set_dest, p -> mem))
+ 	                  {
+ 	                    p -> mem = 0;
+ 	                  }
+ 	              }
+ 	            if (p -> insn_store
+ 	                && (store_pat = PATTERN (p -> insn_store))
+ 	                && GET_CODE (SET_DEST (store_pat)) == MEM
+ 	                && true_dependence (set_dest,
+ 	                    		    SET_DEST (store_pat)))
+ 	              {
+ 	                /* insn_store is not valid any more */
+ 	                p -> insn_store = 0;
+ 	              }
+ 	          }
+ 	      }
+ 
+             if (mhp)
+               {
+                 /* restore the relevant entry */
+ 		*mhp = save_mh;
+ 		mhp -> insn_store = insn;
+ 
+ 		/* if there was no load, we can consider this insn as if it is a
+ 		   load */
+ 		if (! mhp -> insn_load || GET_CODE (mhp -> insn_load) == NOTE)
+ 		  {
+ 		    mhp -> insn_load = insn;
+ 		    mhp -> mem = set_dest;
+ 		  }
+ 	      }
+               update_regno_holds_mem (insn, XEXP (set_dest, 0));
+           }
+         else
+           {
+             update_regno_holds_mem (insn, set_dest);
+             update_regno_holds_mem (insn, set_src);
+           }
+         return;
+       case CLOBBER:
+ 	set_dest = SET_DEST (pat);
+         if (GET_CODE (set_dest) == REG)
+           {
+             register int regno = REGNO (set_dest);
+             register int nregs = HARD_REGNO_NREGS (regno,
+                 				   GET_MODE (set_dest));
+ 
+ 	    if (nregs == 1)
+ 	      {
+ 	        bzero (&regno_holds_mem[regno], sizeof (MEM_HOLDER));
+ 	        update_entries (set_dest);
+               }
+             else
+               /* memory holds more than one register. This is a simplification.
+                  Actually we should zero only those register entries which are
+                  relevant for nregs... */
+               bzero (regno_holds_mem, sizeof regno_holds_mem);
+           }
+         else if (GET_CODE (set_dest) == SUBREG)
+           {
+             regno = REGNO (SUBREG_REG (set_dest));
+             nregs = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (set_dest, 0)));
+ 
+             mhp = &regno_holds_mem[regno];
+             for (; mhp < &regno_holds_mem[regno] + nregs; mhp++)
+               {
+                 bzero (mhp, sizeof (MEM_HOLDER));
+               }
+             if (nregs == 1)
+               {
+                 update_entries (XEXP (set_dest, 0));
+               }
+             else
+               {
+                 /* memory holds more than one register. This is a simplification.
+                    Actually we should zero only those register entries which are
+                    relevant for nregs... */
+                 bzero (regno_holds_mem, sizeof regno_holds_mem);
+               }
+             return;
+           }
+         else if (GET_CODE (set_dest) == MEM)
+           for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+             {
+               /* the mem field indicates that this regno is no more valid for
+                  replacement in loads. Note that this regno might be valid for
+                  redundant store, or even replace loads with memory to which
+                  this reg was writing in the insn_store, and in such case we
+                  would like to reset the risc flags on all insns, from insn_load
+                  to insn_dead. This is why we don't reset here insn_load and
+                  insn_dead. */
+ 	      if (regno_holds_mem[i].mem
+ 	          && GET_CODE (regno_holds_mem[i].mem) == MEM
+ 	          && true_dependence (set_dest, regno_holds_mem[i].mem))
+                 regno_holds_mem[i].mem = 0;
+             }
+         else
+           {
+             fprintf (stderr,
+                      "unpredicted case caused reset of regno_holds_mem:\n");
+             fprintf (stderr, "pattern:\n");
+             debug_rtx (pat);
+             fprintf (stderr, "insn:\n");
+ 	    debug_rtx (insn);
+ 	    bzero (regno_holds_mem, sizeof regno_holds_mem);
+ 	  }
+         return;
+       case CALL:
+         /* since we cannot know what writes to memory in the function call,
+            we must not use the information in regno_holds_mem anymore */
+ 
+ 	bzero (regno_holds_mem, sizeof regno_holds_mem);
+         return;
+       case PRE_DEC:
+       case PRE_INC:
+       case POST_DEC:
+       case POST_INC:
+         if (GET_CODE (XEXP (pat, 0)) == REG)
+           {
+             bzero (&regno_holds_mem[REGNO (XEXP (pat,0))], sizeof (MEM_HOLDER));
+ 	    update_entries (XEXP (pat, 0));
+           }
+         else
+           {
+             update_regno_holds_mem (insn, XEXP (pat, 0));
+           }
+         return;
+       case MEM:
+         /* there is a use of a memory in this insn, we cannot trust the
+            insn_store data anymore */
+         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+           {
+             regno_holds_mem[i].insn_store = 0;
+             if (regno_holds_mem[i].insn_load == NULL)
+               {
+                 regno_holds_mem[i].insn_dead = 0;
+                 regno_holds_mem[i].mem = NULL;
+               }
+           }
+         update_regno_holds_mem (insn, XEXP (pat, 0));
+         return;
+       case USE:
+         update_regno_holds_mem (insn, SET_DEST (pat));
+         return;
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+     case REG:
+     /*case SUBREG:*/
+         /* do nothing */
+         return;
+   }  /* switch (GET_CODE (pat)) */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if( XEXP (pat, i))
+           update_regno_holds_mem (insn, XEXP (pat, i));
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  update_regno_holds_mem (insn, XVECEXP (pat, i, j));
+       }
+ }  /* update_regno_holds_mem (rtx pat) */
+ 
+ 
+ 
+ 
+ /* Invalidates entries of memory mentioning REG in their memories, and the
+    entry of the appropriate REG */
+ 
+ static void
+ update_entries (rtx reg)
+ {
+   register MEM_HOLDER *mhp = regno_holds_mem;
+   register int regno = REGNO (reg);
+ 
+   for (; mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER; mhp++)
+     {
+       if (mhp->mem && reg_overlap_mentioned_p (reg, mhp->mem))
+         {
+           if (mhp->insn_store && mhp->insn_store != mhp->insn_load)
+             {
+               mhp -> insn_load = mhp -> insn_store;
+               mhp -> mem = SET_DEST (PATTERN (mhp -> insn_load));
+               mhp -> insn_dead = 0;
+             }
+           else
+             bzero (mhp, sizeof (MEM_HOLDER));
+         }
+       if (mhp -> insn_store && GET_CODE (mhp -> insn_store) == INSN
+           /* insn_store can be deleted by redundant store elimination */
+           && reg_overlap_mentioned_p (reg, 
+                                       SET_DEST (PATTERN (mhp->insn_store))))
+         {
+           if (mhp->insn_load == mhp->insn_store)
+            {
+               bzero (mhp, sizeof (MEM_HOLDER));
+            }
+           else
+            {
+              mhp -> insn_store = 0;
+            }
+         }
+     }  /* for (; mhp < regno_holds_mem + FIRST_PSEUDO_REGISTER; mhp++) */
+ }  /* update_entries (rtx reg) */
+ 
+ 
+ 
+ /* for each regno found to be non-free (is used or set) from (and including)
+    FIRST, to LAST, clears the appropriate bit in HARD_REG_SET pointed to by
+    FREE. */
+    
+ void
+ find_free_regs_between (free, first, last)
+     HARD_REG_SET *free;
+     rtx first;
+     rtx last;
+ 
+ {
+   rtx insn, pat;
+   char *funcname = "find_free_regs_between";
+   register int i;
+ 
+ 
+   if (! first)
+     abort ();
+   if (! last)
+     abort ();
+ 
+   insn = first;
+   while (insn
+          && insn != last)
+     {
+       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+         {
+           if (GET_CODE (insn) == CALL_INSN)
+             {
+               /* we should reset all regs clobbered by a call */
+               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	        if (call_used_regs[i])
+ 		  CLEAR_HARD_REG_BIT (*free, i);
+ 	    }
+ 	  else  /* GET_RTX_CLASS (GET_CODE (insn)) != 'i' */
+ 	    {
+ 	      pat = PATTERN (insn);
+               for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 		if (INSN_SETS_REGNO (insn, i)
+ 		    || INSN_USES_REGNO (insn, i))
+ 	          CLEAR_HARD_REG_BIT (*free, i);
+ 	    }
+         } /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i') */
+       insn = NEXT_INSN (insn);
+     }
+   if (insn != last)
+     fprintf (stderr, "%s (): didn't encounterd last!\n", funcname);
+   
+ }
+ 
+ /* removes a previous store of MEM if found, and returns INSN_UID of the insn
+    deleted. Otherwise returns 0. */
+ static int
+ remove_redundant_store (rtx mem, int block)
+ {
+   rtx t_insn;
+   int regno;
+ 
+   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+     if ((t_insn = regno_holds_mem[regno].insn_store)
+ 	&& GET_CODE (t_insn) == INSN
+         && rtx_equal_p (SET_DEST (PATTERN (t_insn)), mem))
+       {
+         if (basic_block_head[block] == t_insn)
+           basic_block_head[block] = NEXT_INSN (t_insn);
+         PUT_CODE (t_insn, NOTE);
+         NOTE_LINE_NUMBER (t_insn) = NOTE_INSN_DELETED;
+         NOTE_SOURCE_FILE (t_insn) = 0;
+ 
+         /* if the insn we have just deleted, was preceded with one or two risc
+            additions (i.e. memory_simplify added insns before it), and they are
+            not used for anything else, remove them as well */
+         if (RTX_IS_RISC_P (PREV_INSN (t_insn)))
+           {
+             PUT_CODE (PREV_INSN (t_insn), NOTE);
+             NOTE_LINE_NUMBER (PREV_INSN (t_insn)) = NOTE_INSN_DELETED;
+             NOTE_SOURCE_FILE (PREV_INSN (t_insn)) = 0;
+             if (RTX_IS_RISC_P (PREV_INSN (PREV_INSN (t_insn))))
+               {
+                 PUT_CODE (PREV_INSN (PREV_INSN (t_insn)), NOTE);
+                 NOTE_LINE_NUMBER (PREV_INSN (PREV_INSN (t_insn)))
+                 					    = NOTE_INSN_DELETED;
+                 NOTE_SOURCE_FILE (PREV_INSN (PREV_INSN (t_insn))) = 0;
+               }
+           }
+            
+         return INSN_UID (t_insn);
+       }
+   return 0;
+ }  /* remove_redundant_store (rtx mem) */
+ 
+ /* intel2 - end */
+ /* intel1 */
+ 
+ /*
+   Try to eliminate unnecessary reg to reg moves, and also
+   if the destination is a register try to use that register
+   as one of the sources.  
+ 
+   EXAMPLE:
+ 
+ (insn 618 614 616 (set (reg:SI %eax)
+         (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
+                     (const_int 4))
+                 (reg:SI %esi)))) -1 (nil)
+     (nil))
+ 
+ (insn 616 618 59 (set (reg:SI %esi)
+         (mem:SI (plus:SI (reg:SI %esp)
+                 (const_int 36)))) -1 (nil)
+     (nil))
+ 
+ (insn:HI 59 616 60 (set (reg:SI %eax)
+         (ior:SI (reg:SI %eax)
+             (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
+                         (const_int 4))
+                     (reg:SI %esi))))) 105 {iorsi3} (nil)
+     (nil))
+ 
+ (insn 60 59 620 (set (reg:SI %eax)
+         (not:SI (reg:SI %eax))) 130 {one_cmplsi2} (insn_list 59 (nil))
+         (nil))
+ 
+ (insn 620 60 61 (set (reg/v:SI %ecx)
+         (reg:SI %eax)) -1 (nil)
+     (expr_list:REG_DEAD (reg:SI %eax)
+     (nil)))
+ 
+ WILL BECOME:
+ 
+ (insn 618 614 616 (set (reg:SI %ecx)
+         (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
+                     (const_int 4))
+                 (reg:SI %esi)))) -1 (nil)
+     (nil))
+ 
+ (insn 616 618 59 (set (reg:SI %esi)
+         (mem:SI (plus:SI (reg:SI %esp)
+                 (const_int 36)))) -1 (nil)
+     (nil))
+ 
+ (insn:HI 59 616 60 (set (reg:SI %ecx)
+         (ior:SI (reg:SI %ecx)
+             (mem/s:SI (plus:SI (mult:SI (reg/v:SI %ebx)
+                         (const_int 4))
+                     (reg:SI %esi))))) 105 {iorsi3} (nil)
+     (nil))
+ 
+ (insn 60 59 620 (set (reg:SI %ecx)
+         (not:SI (reg:SI %ecx))) 130 {one_cmplsi2} (insn_list 59 (nil))
+         (nil))
+ 
+ (note 620 60 61 "" NOTE_INSN_DELETED)
+ 
+ 
+ The trigger for the optimization is:
+ 
+ (insn 620 60 61 (set (reg/v:SI %ecx)
+         (reg:SI %eax)) -1 (nil)
+     (expr_list:REG_DEAD (reg:SI %eax)
+     (nil)))
+ 
+ */
+ void
+ reg_to_reg_copy_opt (f, file)
+      rtx f;
+      FILE *file;
+ {
+   rtx this_insn, regx, note, src;
+   int regno, success, length, i;
+   char * fmt;
+ 
+   if (file)
+     {
+       fprintf (file, "\n\ndoing reg to reg copy opt\n");
+     }
+   hard_reg_flow_analysis (f, NULL, 1);
+   this_insn = f;
+   while (this_insn)
+     {
+       if (GET_CODE (this_insn) == INSN 
+           && GET_CODE (PATTERN (this_insn)) == SET
+           && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
+           && GET_CODE (SET_SRC (PATTERN (this_insn))) == REG
+           && REGNO (SET_SRC (PATTERN (this_insn))) 
+              != REGNO (SET_DEST (PATTERN (this_insn))) 
+           && GET_MODE (SET_SRC (PATTERN (this_insn))) 
+              == GET_MODE (SET_DEST (PATTERN (this_insn))) 
+           && find_regno_note (this_insn, REG_DEAD, 
+                               REGNO (SET_SRC (PATTERN (this_insn))))
+          )
+         {
+           success = try_backwards_replace (SET_DEST (PATTERN (this_insn)), 
+                                  SET_SRC (PATTERN (this_insn)),
+                                  this_insn, 1, file);
+           if (!success)
+             {
+                success = try_forwards_replace (SET_DEST (PATTERN (this_insn)), 
+                                  SET_SRC (PATTERN (this_insn)),
+                                  this_insn, file);
+             }
+         }
+       else if (GET_CODE (this_insn) == INSN 
+                && GET_CODE (PATTERN (this_insn)) == SET
+                && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
+                && GET_CODE (SET_SRC (PATTERN (this_insn))) == SUBREG
+                && REGNO (SET_DEST (PATTERN (this_insn))) 
+                   != REGNO (SUBREG_REG (SET_SRC (PATTERN (this_insn))))
+                && SUBREG_WORD (SET_SRC (PATTERN (this_insn))) == 0
+                && GET_MODE (SET_SRC (PATTERN (this_insn))) 
+                   == GET_MODE (SET_DEST (PATTERN (this_insn))) 
+                && (note = find_regno_note (this_insn, REG_DEAD, 
+                                    REGNO (SUBREG_REG (SET_SRC (PATTERN (this_insn))))))
+                && rtx_equal_p (XEXP (note, 0), 
+                                SUBREG_REG (SET_SRC (PATTERN (this_insn))))
+                && HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
+             		            GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))))
+                    ==
+                   HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
+             			    GET_MODE (SET_DEST (PATTERN (this_insn))))
+                && HARD_REGNO_NREGS (REGNO (SET_DEST (PATTERN (this_insn))),
+             			    GET_MODE (SET_DEST (PATTERN (this_insn))))
+                    == 1
+                && HARD_REGNO_MODE_OK (REGNO (SET_DEST (PATTERN (this_insn))) ,
+                                       GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))))
+               )
+         {
+           regx = gen_rtx (REG, 
+                           GET_MODE (SUBREG_REG (SET_SRC (PATTERN (this_insn)))),
+                           REGNO (SET_DEST (PATTERN (this_insn))));
+           success 
+            = try_backwards_replace (regx,
+                                  SUBREG_REG (SET_SRC (PATTERN (this_insn))),
+                                  this_insn, 1, file);
+           if (!success)
+             {
+               success 
+                = try_forwards_replace (SET_DEST (PATTERN (this_insn)),
+                                  SET_SRC (PATTERN (this_insn)),
+                                  this_insn, file);
+             }
+         }
+       else if (GET_CODE (this_insn) == INSN 
+           && GET_CODE (PATTERN (this_insn)) == SET
+           && GET_CODE (SET_DEST (PATTERN (this_insn))) == REG
+           && GET_CODE (SET_SRC (PATTERN (this_insn))) != MEM
+           && GET_CODE (SET_SRC (PATTERN (this_insn))) != SUBREG
+           && !reg_overlap_mentioned_p (SET_DEST (PATTERN (this_insn)),
+                                        SET_SRC (PATTERN (this_insn)))
+           )
+         {
+           src = SET_SRC (PATTERN (this_insn));
+           fmt = GET_RTX_FORMAT (GET_CODE (src));
+           length = GET_RTX_LENGTH (GET_CODE (src));
+           for (i=0; i<length; i++)
+             {
+               if (fmt[i] == 'e' 
+                   && GET_CODE (XEXP (src, i)) == SUBREG)
+                 {  /* Makes matters too complex.  */
+                   return;
+                 }
+             }
+           for (i=0; i<length; i++)
+             {
+               if (fmt[i] == 'e' 
+                   && GET_CODE (XEXP (src, i)) == REG
+                   && (note = find_regno_note (this_insn, REG_DEAD,
+                                               REGNO (XEXP (src, i))))
+                   && rtx_equal_p (XEXP (src, i), XEXP (note, 0))
+                   )
+                 { /* One of the sources dies in this insn -
+                      see if the destination register can be used
+                      to replace that register.  This has a chance
+                      of producing better code e.g. reg1 <- reg1 AND reg3
+                      produces more efficient code than 
+                      reg1 <- reg2 AND reg3.  */
+                   rtx regx, regy;
+                   regy = XEXP (src, i);
+                   regx = SET_DEST (PATTERN (this_insn));
+                   if (reg_overlap_mentioned_p (regx, PATTERN (this_insn)))
+                     {
+                       break;
+                     }
+                   if (GET_MODE (regx) != GET_MODE (regy))
+                     {
+                       if (HARD_REGNO_NREGS (REGNO (regx), GET_MODE (regy)) != 1
+                           || 
+                           !(HARD_REGNO_MODE_OK (REGNO (regx), GET_MODE (regy))))
+                         {
+                           continue;
+                         }
+                       regx = gen_rtx (REG, GET_MODE (regy), REGNO (regx)); 
+                     }
+                   if (try_backwards_replace (regx, regy, this_insn, 0, file))
+                     {
+                       remove_note (this_insn, note);
+                       break; /* Since now the dest reg is 
+                                 mentioned in the src.  */
+                     }
+                 }
+             }
+ 
+         }
+       this_insn = NEXT_INSN (this_insn);
+     }
+   if (file)
+     {
+       fprintf (file, "\n");
+     }
+ }
+ 
+ /*
+   insn is of the form
+      regx <- regy (regy dead)
+    or
+      regx <- SUBREG (regy) (regy dead)
+    or
+      regx <- OP (regy, ...) (regy dead)
+    
+   Search backwards for last previous setting of regy in which the 
+   setting of regy can be replaced with regx.  If it can then
+   do the replacement and then if delete_flag is set delete insn.  
+ */
+ 
+ static
+ int
+ try_backwards_replace (regx, regy, insn, delete_flag, file)
+   rtx regx, regy, insn;
+   FILE *file;
+ {
+   rtx this_insn, set_insn, stop_insn;
+   int stop_replacement = 0;
+   int found = 0, insn_code_number, not_yet_recoged;
+   
+   
+   if (file)
+     {
+       fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try backwards)\n", 
+       INSN_UID(insn), REGNO (regx), REGNO (regy), REGNO(regy));
+     }
+   this_insn = prev_nonnote_insn (insn);
+   /* Find the first previous insn in the block that sets regy and in
+      which regy can be replaced with regx */
+   while (!found && this_insn 
+          && !(GET_CODE (this_insn) == CODE_LABEL 
+               || GET_CODE (this_insn) == CALL_INSN
+               || GET_CODE (this_insn) == JUMP_INSN))
+     {
+       if (GET_CODE (this_insn) == INSN)
+         {
+           if (GET_CODE (PATTERN (this_insn)) != SET)
+             {
+               return (0);
+             }
+           if (GET_CODE (SET_DEST (PATTERN (this_insn))) == REG)
+             {
+               if (REGNO (regx) == REGNO (SET_DEST (PATTERN (this_insn))))
+                 {
+                   return (0);
+                 }
+               else if (REGNO (regy) == REGNO (SET_DEST (PATTERN (this_insn))))
+                 {
+                   if (GET_MODE (regy) 
+                        == GET_MODE (SET_DEST (PATTERN (this_insn))))
+                     {
+ #ifdef REGISTER_CONSTRAINTS
+                       if (INSN_CODE (this_insn) == -1)
+                         {
+                           INSN_CODE (this_insn) 
+                             = recog (PATTERN (this_insn), this_insn, 0);
+                         }
+ #endif
+                       SET_DEST (PATTERN (this_insn)) = regx;
+ #ifdef REGISTER_CONSTRAINTS
+ 
+ 	              if ((insn_code_number
+ 	                   = recog (PATTERN (this_insn), this_insn, 0)) < 0
+                           || (INSN_CODE (this_insn) != -1
+                               && insn_code_number != INSN_CODE (this_insn)))
+ 	                {/* Need to have the same code number since 
+ 	                    constraints are sometimes more lax than 
+ 	                    predicates */
+ 		          SET_DEST (PATTERN (this_insn)) = regy;
+ 		          stop_replacement = 1;
+ 		        }
+ 		        else
+ 	                {
+ 	                  INSN_CODE (this_insn) = insn_code_number;
+ 		          insn_extract (this_insn);
+ 		          if(!constrain_operands (INSN_CODE (this_insn), 1))
+ 	                    {
+ 		              /* restore the previous situation */
+ 	  	              SET_DEST (PATTERN (this_insn)) = regy;
+ 	                      /*INSN_CODE (this_insn) 
+ 	                       = recog (PATTERN (this_insn), this_insn, 0);*/
+ 		              stop_replacement = 1;
+  		            }
+ 		        }
+         
+ #endif
+                       if (!stop_replacement)
+                         {
+                           found = 1;
+                           set_insn = this_insn;
+                         }
+                     }
+                   else
+                     {
+                       return (0);
+                     }
+                 }
+             }
+           else if (reg_overlap_mentioned_p (regx, SET_DEST (PATTERN (this_insn))))
+             {
+               return (0);
+             }
+           if (!found
+               && reg_overlap_mentioned_p (regx, SET_SRC (PATTERN (this_insn))))
+             {
+               return (0);
+             }
+         }
+       if (!found)
+         {
+           stop_replacement = 0;
+           this_insn = prev_nonnote_insn (this_insn);
+         }
+     }
+   if (found)
+     {/* We have found the insn that last sets regy and successfully 
+         replaced regx as the dest of that insn.  
+         In all insns between set_insn and insn replace regy with regx.  */
+       stop_replacement = 0;
+       this_insn = next_nonnote_insn (set_insn);
+       init_undo_buf ();
+       stop_insn = next_nonnote_insn (insn);
+       while (this_insn != stop_insn && !stop_replacement)
+         {
+ #ifdef REGISTER_CONSTRAINTS
+           if (INSN_CODE (this_insn) == -1)
+             {
+               INSN_CODE (this_insn) 
+                 = recog (PATTERN (this_insn), this_insn, 0);
+             }
+ #endif
+           subst_in_insn (this_insn, PATTERN (this_insn), regy, regx, 0, 0);
+           if (reg_set_p (regy, this_insn)
+               || reg_overlap_mentioned_p (regy, PATTERN (this_insn)))
+             { /* regy was used in some other mode - fail */
+               stop_replacement = 1;
+             }
+ #ifdef REGISTER_CONSTRAINTS
+           if (stop_replacement
+               ||
+               (insn_code_number
+                 = recog (PATTERN (this_insn), this_insn, 0)) < 0
+               || (INSN_CODE (this_insn) != -1
+                   && insn_code_number != INSN_CODE (this_insn)))
+             {/* Need to have the same code number since constraints
+                  are sometimes more lax than predicates */
+               stop_replacement = 1;
+             }
+           else
+             {
+               INSN_CODE (this_insn) = insn_code_number;
+               insn_extract (this_insn);
+ 	      if(!constrain_operands (INSN_CODE (this_insn), 1))
+ 	        {
+ 	          stop_replacement = 1;
+ 	        }
+             }
+ #endif
+           this_insn = next_nonnote_insn ( this_insn);
+         }
+         
+       if (stop_replacement)
+         { /* A replacement was unsuccessful - undo all of the replacements */
+           SET_DEST (PATTERN (set_insn)) = regy;
+           /*INSN_CODE (this_insn) 
+             = recog (PATTERN (this_insn), this_insn, 0);*/
+           this_insn = next_nonnote_insn (set_insn);
+           loop_undo_all ();
+           /*while (this_insn != insn)
+             {
+               INSN_CODE (this_insn) 
+                 = recog (PATTERN (this_insn), this_insn, 0); 
+               this_insn = next_nonnote_insn (this_insn);
+             }*/
+           return (0);
+         }
+       else 
+         { 
+ 	  if (file)
+ 	    {
+ 	      fprintf (file, "replaced dest reg%d of insn %d with reg%d\n",
+ 	        REGNO (regy), INSN_UID (set_insn), REGNO (regx));
+ 	      fprintf (file, " in insns %d through %d replaced reg%d with reg%d\n",
+ 	        INSN_UID (next_nonnote_insn (set_insn)),
+ 	        INSN_UID (insn), 
+ 	        REGNO (regy), REGNO (regx));
+ 	    }
+           if (delete_flag)
+             {/* Delete insn */
+               PUT_CODE (insn, NOTE);
+ 	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 	      NOTE_SOURCE_FILE (insn) = 0;
+ 	      if (file)
+ 	        {
+ 	          fprintf (file, " deleted insn %d\n", INSN_UID (insn));
+ 	        }
+ 	    }
+           return (1);
+         }
+     }
+   return (0);
+ }
+ 
+ 
+ /*
+   insn is of the form
+      regx <- regy (regy dead)
+    or
+      regx <- SUBREG (regy) (regy dead)
+    
+   Search forwards for next insn in which the regx is dead.
+   Try to replace all uses of regx with regy in those insns
+   and if successful then delete insn.  
+ */
+ 
+ static
+ int
+ try_forwards_replace (regx, regy, insn, file)
+   rtx regx, regy, insn;
+   FILE *file;
+ {
+   rtx this_insn, dead_insn, dead_note, stop_insn;
+   int stop_replacement = 0;
+   int found = 0, insn_code_number;
+   
+   
+   if (file)
+     {
+       if (GET_CODE (regy) == REG )
+         fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try forwards)\n", 
+         INSN_UID(insn), REGNO (regx), REGNO (regy), REGNO(regy));
+       else
+         fprintf (file, "\ninsn %d reg%d <- reg%d (reg%d dead) (try forwards)\n", 
+         INSN_UID(insn), REGNO (regx), 
+         REGNO (SUBREG_REG (regy)), 
+         REGNO (SUBREG_REG (regy)));
+     }
+   this_insn = next_nonnote_insn (insn);
+   /* Find the next insn in the block where regx dies */
+   while (!found && this_insn 
+          && !(GET_CODE (this_insn) == CODE_LABEL 
+               || GET_CODE (this_insn) == CALL_INSN
+               || GET_CODE (this_insn) == JUMP_INSN))
+     {
+       if (GET_CODE (this_insn) == INSN)
+         {
+           if (GET_CODE (PATTERN (insn)) == USE
+               && reg_overlap_mentioned_p (regx, SET_DEST (PATTERN (insn))))
+             {
+               return (0);
+             }
+           if (reg_set_p (regy, this_insn))
+             {
+               return (0);
+             }
+           else if ((dead_note 
+                     = find_regno_note (this_insn, REG_DEAD, REGNO (regx)))
+                    && rtx_equal_p (XEXP (dead_note, 0), regx))
+             {
+               found = 1;
+               dead_insn = this_insn;
+             }
+         }
+       if (!found)
+         {
+           this_insn = next_nonnote_insn (this_insn);
+         }
+     }
+   if (found)
+     {/* We have found the insn where regx dies.  */
+       stop_replacement = 0;
+       this_insn = next_nonnote_insn (insn);
+       init_undo_buf ();
+       stop_insn = next_nonnote_insn (dead_insn);
+       while (this_insn != stop_insn && !stop_replacement)
+         {
+ #ifdef REGISTER_CONSTRAINTS
+           if (INSN_CODE (this_insn) == -1)
+             {
+               INSN_CODE (this_insn) 
+                 = recog (PATTERN (this_insn), this_insn, 0);
+             }
+ #endif
+           subst_in_insn (this_insn, PATTERN (this_insn), regx, regy, 0, 0);
+           if (reg_set_p (regx, this_insn)
+               || reg_overlap_mentioned_p (regx, PATTERN (this_insn)))
+             { /* regx is used in some other mode - fail.  */
+               if (file)
+                 {
+                   fprintf (file, "fail insn %d reg %d still mentioned\n",
+                   INSN_UID (this_insn), REGNO (regx));
+                   tdebug_rtx (this_insn, file);
+                 }
+               stop_replacement = 1;
+             }
+ #ifdef REGISTER_CONSTRAINTS
+           if (stop_replacement
+               ||
+               (insn_code_number
+                 = recog (PATTERN (this_insn), this_insn, 0)) < 0
+               || (INSN_CODE (this_insn) != -1
+                   && insn_code_number != INSN_CODE (this_insn)))
+             { /* Need to have the same code number since constraints
+                  are sometimes more lax than predicates */
+               if (file)
+                 {
+                   fprintf (file, "fail insn %d new_recog %d old_recog %d\n",
+                   INSN_UID (this_insn), insn_code_number, INSN_CODE (this_insn));
+                 }
+               stop_replacement = 1;
+             }
+           else
+             {
+               INSN_CODE (this_insn) = insn_code_number;
+               insn_extract (this_insn);
+ 	      if(!constrain_operands (INSN_CODE (this_insn), 1))
+ 	        {
+ 	          stop_replacement = 1;
+ 	        }
+             }
+ #endif
+           this_insn = next_nonnote_insn ( this_insn);
+         }
+         
+       if (stop_replacement)
+         { /* A replacement was unsuccessful - undo all of the replacements */
+           this_insn = next_nonnote_insn (insn);
+           loop_undo_all ();
+           stop_insn = next_nonnote_insn (dead_insn);
+           /*while (this_insn != stop_insn)
+             {
+               INSN_CODE (this_insn) 
+                  = recog (PATTERN (this_insn), this_insn, 0); 
+               this_insn = next_nonnote_insn (this_insn);
+             }*/
+           return (0);
+         }
+       else
+         { /* Delete insn */
+           PUT_CODE (insn, NOTE);
+ 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 	  NOTE_SOURCE_FILE (insn) = 0;
+ 	  XEXP (dead_note, 0) = regy;
+ 	  if (file)
+ 	    {
+ 	      fprintf (file, " in insns %d through %d replaced reg%d with reg%d\n",
+ 		       INSN_UID (next_nonnote_insn (insn)),
+ 		       INSN_UID (dead_insn), 
+ 		       REGNO (regx), 
+ 		       GET_CODE (regy) == REG 
+ 		         ? REGNO (regy)
+ 		         : REGNO (SUBREG_REG (regy)));
+ 	      fprintf (file, " deleted insn %d\n", INSN_UID (insn));
+ 	    }
+           return (1);
+         }
+     }
+   return (0);
  }
diff -rNci gcc-2.7.2/config/i386/i386.c gcc-2.7.2p/config/i386/i386.c
*** gcc-2.7.2/config/i386/i386.c	Sun Oct 22 11:13:21 1995
--- gcc-2.7.2p/config/i386/i386.c	Tue Jan 23 09:34:59 1996
***************
*** 1,6 ****
--- 1,9 ----
  /* Subroutines for insn-output.c for Intel X86.
     Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
  
+    Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
+    (tevi@iil.intel.com).
+   
  This file is part of GNU CC.
  
  GNU CC is free software; you can redistribute it and/or modify
***************
*** 35,40 ****
--- 38,45 ----
  #include "flags.h"
  #include "function.h"
  
+ /* intel1 Need the EXTRA_CONSTRAINT - changed s to */
+ #if 0
  #ifdef EXTRA_CONSTRAINT
  /* If EXTRA_CONSTRAINT is defined, then the 'S'
     constraint in REG_CLASS_FROM_LETTER will no longer work, and various
***************
*** 43,48 ****
--- 48,57 ----
  /* The previous line used to be #error, but some compilers barf
     even if the conditional was untrue.  */
  #endif
+ #endif
+ 
+ /* which cpu are we scheduling for intel1*/
+ enum processor_type x86_cpu;
  
  #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
  
***************
*** 53,88 ****
  char *output_move_const_single ();
  char *output_fp_cc0_set ();
  
  char *hi_reg_name[] = HI_REGISTER_NAMES;
  char *qi_reg_name[] = QI_REGISTER_NAMES;
  char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
  
- /* Array of the smallest class containing reg number REGNO, indexed by
-    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
- 
- enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
- {
-   /* ax, dx, cx, bx */
-   AREG, DREG, CREG, BREG,
-   /* si, di, bp, sp */
-   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
-   /* FP registers */
-   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
-   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
-   /* arg pointer */
-   INDEX_REGS
- };
- 
- /* Test and compare insns in i386.md store the information needed to
-    generate branch and scc insns here.  */
- 
- struct rtx_def *i386_compare_op0 = NULL_RTX;
- struct rtx_def *i386_compare_op1 = NULL_RTX;
- struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
- 
  /* Register allocation order */
  char *i386_reg_alloc_order;
! static char regs_allocated[FIRST_PSEUDO_REGISTER];
  
  /* # of registers to use to pass arguments. */
  char *i386_regparm_string;			/* # registers to use to pass args */
--- 62,77 ----
  char *output_move_const_single ();
  char *output_fp_cc0_set ();
  
+ /* intel1 */
+ static int opt_level=0;
+ 
  char *hi_reg_name[] = HI_REGISTER_NAMES;
  char *qi_reg_name[] = QI_REGISTER_NAMES;
  char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
  
  /* Register allocation order */
  char *i386_reg_alloc_order;
! /*static char regs_allocated[FIRST_PSEUDO_REGISTER];*/
  
  /* # of registers to use to pass arguments. */
  char *i386_regparm_string;			/* # registers to use to pass args */
***************
*** 97,284 ****
  int i386_align_jumps;				/* power of two alignment for non-loop jumps */
  int i386_align_funcs;				/* power of two alignment for functions */
  
! 
! /* Sometimes certain combinations of command options do not make
!    sense on a particular target machine.  You can define a macro
!    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
!    defined, is executed once just after all the command options have
!    been parsed.
! 
!    Don't use this macro to turn on various extra optimizations for
!    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
! 
! void
! override_options ()
! {
!   int ch, i, regno;
!   char *p;
!   int def_align;
! 
! #ifdef SUBTARGET_OVERRIDE_OPTIONS
!   SUBTARGET_OVERRIDE_OPTIONS;
! #endif
! 
!   /* Validate registers in register allocation order */
!   if (i386_reg_alloc_order)
!     {
!       for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
! 	{
! 	  switch (ch)
! 	    {
! 	    case 'a':	regno = 0;	break;
! 	    case 'd':	regno = 1;	break;
! 	    case 'c':	regno = 2;	break;
! 	    case 'b':	regno = 3;	break;
! 	    case 'S':	regno = 4;	break;
! 	    case 'D':	regno = 5;	break;
! 	    case 'B':	regno = 6;	break;
! 
! 	    default:	fatal ("Register '%c' is unknown", ch);
! 	    }
! 
! 	  if (regs_allocated[regno])
! 	    fatal ("Register '%c' was already specified in the allocation order", ch);
! 
! 	  regs_allocated[regno] = 1;
! 	}
!     }
! 
!   /* Validate -mregparm= value */
!   if (i386_regparm_string)
!     {
!       i386_regparm = atoi (i386_regparm_string);
!       if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
! 	fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
!     }
! 
!   def_align = (TARGET_386) ? 2 : 4;
! 
!   /* Validate -malign-loops= value, or provide default */
!   if (i386_align_loops_string)
!     {
!       i386_align_loops = atoi (i386_align_loops_string);
!       if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
! 	fatal ("-malign-loops=%d is not between 0 and %d",
! 	       i386_align_loops, MAX_CODE_ALIGN);
!     }
!   else
!     i386_align_loops = 2;
! 
!   /* Validate -malign-jumps= value, or provide default */
!   if (i386_align_jumps_string)
!     {
!       i386_align_jumps = atoi (i386_align_jumps_string);
!       if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
! 	fatal ("-malign-jumps=%d is not between 0 and %d",
! 	       i386_align_jumps, MAX_CODE_ALIGN);
!     }
!   else
!     i386_align_jumps = def_align;
! 
!   /* Validate -malign-functions= value, or provide default */
!   if (i386_align_funcs_string)
!     {
!       i386_align_funcs = atoi (i386_align_funcs_string);
!       if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
! 	fatal ("-malign-functions=%d is not between 0 and %d",
! 	       i386_align_funcs, MAX_CODE_ALIGN);
!     }
!   else
!     i386_align_funcs = def_align;
! }
! 
! /* A C statement (sans semicolon) to choose the order in which to
!    allocate hard registers for pseudo-registers local to a basic
!    block.
! 
!    Store the desired register order in the array `reg_alloc_order'.
!    Element 0 should be the register to allocate first; element 1, the
!    next register; and so on.
! 
!    The macro body should not assume anything about the contents of
!    `reg_alloc_order' before execution of the macro.
! 
!    On most machines, it is not necessary to define this macro.  */
  
! void
! order_regs_for_local_alloc ()
  {
!   int i, ch, order, regno;
! 
!   /* User specified the register allocation order */
!   if (i386_reg_alloc_order)
!     {
!       for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
! 	{
! 	  switch (ch)
! 	    {
! 	    case 'a':	regno = 0;	break;
! 	    case 'd':	regno = 1;	break;
! 	    case 'c':	regno = 2;	break;
! 	    case 'b':	regno = 3;	break;
! 	    case 'S':	regno = 4;	break;
! 	    case 'D':	regno = 5;	break;
! 	    case 'B':	regno = 6;	break;
! 	    }
! 
! 	  reg_alloc_order[order++] = regno;
! 	}
! 
!       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	{
! 	  if (!regs_allocated[i])
! 	    reg_alloc_order[order++] = i;
! 	}
!     }
! 
!   /* If users did not specify a register allocation order, favor eax
!      normally except if DImode variables are used, in which case
!      favor edx before eax, which seems to cause less spill register
!      not found messages.  */
!   else
!     {
!       rtx insn;
! 
!       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! 	reg_alloc_order[i] = i;
! 
!       if (optimize)
! 	{
! 	  int use_dca = FALSE;
! 
! 	  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
! 	    {
! 	      if (GET_CODE (insn) == INSN)
! 		{
! 		  rtx set = NULL_RTX;
! 		  rtx pattern = PATTERN (insn);
! 
! 		  if (GET_CODE (pattern) == SET)
! 		    set = pattern;
! 
! 		  else if ((GET_CODE (pattern) == PARALLEL
! 			    || GET_CODE (pattern) == SEQUENCE)
! 			   && GET_CODE (XVECEXP (pattern, 0, 0)) == SET)
! 		    set = XVECEXP (pattern, 0, 0);
! 
! 		  if (set && GET_MODE (SET_SRC (set)) == DImode)
! 		    {
! 		      use_dca = TRUE;
! 		      break;
! 		    }
! 		}
! 	    }
  
! 	  if (use_dca)
! 	    {
! 	      reg_alloc_order[0] = 1;	/* edx */
! 	      reg_alloc_order[1] = 2;	/* ecx */
! 	      reg_alloc_order[2] = 0;	/* eax */
! 	    }
! 	}
!     }
! }
  
  
  /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
     attribute for DECL.  The attributes in ATTRIBUTES have previously been
--- 86,112 ----
  int i386_align_jumps;				/* power of two alignment for non-loop jumps */
  int i386_align_funcs;				/* power of two alignment for functions */
  
! /* Array of the smallest class containing reg number REGNO, indexed by
!    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
  
! enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
  {
!   /* ax, dx, cx, bx */
!   AREG, DREG, CREG, BREG,
!   /* si, di, bp, sp */
!   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
!   /* FP registers */
!   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
!   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,       
!   /* arg pointer */
!   INDEX_REGS
! };
  
! /* Test and compare insns in i386.md store the information needed to
!    generate branch and scc insns here.  */
  
+ struct rtx_def *i386_compare_op0, *i386_compare_op1;
+ struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
  
  /* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
     attribute for DECL.  The attributes in ATTRIBUTES have previously been
***************
*** 635,640 ****
--- 463,469 ----
       int dies;
  {
    rtx xops[4];
+   int def_align;
    int size = GET_MODE_SIZE (GET_MODE (dest));
  
    xops[0] = AT_SP (Pmode);
***************
*** 681,686 ****
--- 510,558 ----
  	  output_asm_insn (AS1 (pop%L0,%0), &dest);
  	}
      }
+ 
+   /* Validate -mregparm= value */
+   if (i386_regparm_string)
+     {
+       i386_regparm = atoi (i386_regparm_string);
+       if (i386_regparm < 0 || i386_regparm > REGPARM_MAX)
+ 	fatal ("-mregparm=%d is not between 0 and %d", i386_regparm, REGPARM_MAX);
+     }
+ 
+   def_align = (TARGET_386) ? 2 : 4;
+ 
+   /* Validate -malign-loops= value, or provide default */
+   if (i386_align_loops_string)
+     {
+       i386_align_loops = atoi (i386_align_loops_string);
+       if (i386_align_loops < 0 || i386_align_loops > MAX_CODE_ALIGN)
+ 	fatal ("-malign-loops=%d is not between 0 and %d",
+ 	       i386_align_loops, MAX_CODE_ALIGN);
+     }
+   else
+     i386_align_loops = 2;
+ 
+   /* Validate -malign-jumps= value, or provide default */
+   if (i386_align_jumps_string)
+     {
+       i386_align_jumps = atoi (i386_align_jumps_string);
+       if (i386_align_jumps < 0 || i386_align_jumps > MAX_CODE_ALIGN)
+ 	fatal ("-malign-jumps=%d is not between 0 and %d",
+ 	       i386_align_jumps, MAX_CODE_ALIGN);
+     }
+   else
+     i386_align_jumps = def_align;
+ 
+   /* Validate -malign-functions= value, or provide default */
+   if (i386_align_funcs_string)
+     {
+       i386_align_funcs = atoi (i386_align_funcs_string);
+       if (i386_align_funcs < 0 || i386_align_funcs > MAX_CODE_ALIGN)
+ 	fatal ("-malign-functions=%d is not between 0 and %d",
+ 	       i386_align_funcs, MAX_CODE_ALIGN);
+     }
+   else
+     i386_align_funcs = def_align;
  }
  
  char *
***************
*** 735,741 ****
    abort ();
  }
  
- 
  /* Output an insn to add the constant N to the register X.  */
  
  static void
--- 607,612 ----
***************
*** 744,768 ****
       rtx x;
  {
    rtx xops[2];
!   xops[0] = x;
! 
!   if (n == -1)
!     output_asm_insn (AS1 (dec%L0,%0), xops);
!   else if (n == 1)
!     output_asm_insn (AS1 (inc%L0,%0), xops);
!   else if (n < 0)
      {
!       xops[1] = GEN_INT (-n);
!       output_asm_insn (AS2 (sub%L0,%1,%0), xops);
      }
    else if (n > 0)
      {
!       xops[1] = GEN_INT (n);
!       output_asm_insn (AS2 (add%L0,%1,%0), xops);
      }
  }
  
- 
  /* Output assembler code to perform a doubleword move insn
     with operands OPERANDS.  */
  
--- 615,633 ----
       rtx x;
  {
    rtx xops[2];
!   xops[1] = x;
!   if (n < 0)
      {
!       xops[0] = GEN_INT (-n);
!       output_asm_insn (AS2 (sub%L0,%0,%1), xops);
      }
    else if (n > 0)
      {
!       xops[0] = GEN_INT (n);
!       output_asm_insn (AS2 (add%L0,%0,%1), xops);
      }
  }
  
  /* Output assembler code to perform a doubleword move insn
     with operands OPERANDS.  */
  
***************
*** 1081,1342 ****
  
    return "";
  }
- 
  
! #define MAX_TMPS 2		/* max temporary registers used */
! 
! /* Output the appropriate code to move push memory on the stack */
! 
! char *
! output_move_pushmem (operands, insn, length, tmp_start, n_operands)
!      rtx operands[];
!      rtx insn;
!      int length;
!      int tmp_start;
!      int n_operands;
  {
  
!   struct {
!     char *load;
!     char *push;
!     rtx   xops[2];
!   } tmp_info[MAX_TMPS];
! 
!   rtx src = operands[1];
!   int max_tmps = 0;
!   int offset = 0;
!   int stack_p = reg_overlap_mentioned_p (stack_pointer_rtx, src);
!   int stack_offset = 0;
!   int i, num_tmps;
!   rtx xops[1];
  
!   if (!offsettable_memref_p (src))
!     fatal_insn ("Source is not offsettable", insn);
  
!   if ((length & 3) != 0)
!     fatal_insn ("Pushing non-word aligned size", insn);
  
!   /* Figure out which temporary registers we have available */
!   for (i = tmp_start; i < n_operands; i++)
!     {
!       if (GET_CODE (operands[i]) == REG)
! 	{
! 	  if (reg_overlap_mentioned_p (operands[i], src))
! 	    continue;
  
! 	  tmp_info[ max_tmps++ ].xops[1] = operands[i];
! 	  if (max_tmps == MAX_TMPS)
! 	    break;
! 	}
!     }
  
!   if (max_tmps == 0)
!     for (offset = length - 4; offset >= 0; offset -= 4)
!       {
! 	xops[0] = adj_offsettable_operand (src, offset + stack_offset);
! 	output_asm_insn (AS1(push%L0,%0), xops);
! 	if (stack_p)
! 	  stack_offset += 4;
!       }
  
!   else
!     for (offset = length - 4; offset >= 0; )
!       {
! 	for (num_tmps = 0; num_tmps < max_tmps && offset >= 0; num_tmps++)
! 	  {
! 	    tmp_info[num_tmps].load    = AS2(mov%L0,%0,%1);
! 	    tmp_info[num_tmps].push    = AS1(push%L0,%1);
! 	    tmp_info[num_tmps].xops[0] = adj_offsettable_operand (src, offset + stack_offset);
! 	    offset -= 4;
! 	  }
  
! 	for (i = 0; i < num_tmps; i++)
! 	  output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
  
! 	for (i = 0; i < num_tmps; i++)
! 	  output_asm_insn (tmp_info[i].push, tmp_info[i].xops);
  
! 	if (stack_p)
! 	  stack_offset += 4*num_tmps;
!       }
  
!   return "";
  }
- 
  
! 
! /* Output the appropriate code to move data between two memory locations */
! 
! char *
! output_move_memory (operands, insn, length, tmp_start, n_operands)
!      rtx operands[];
!      rtx insn;
!      int length;
!      int tmp_start;
!      int n_operands;
! {
!   struct {
!     char *load;
!     char *store;
!     rtx   xops[3];
!   } tmp_info[MAX_TMPS];
! 
!   rtx dest = operands[0];
!   rtx src  = operands[1];
!   rtx qi_tmp = NULL_RTX;
!   int max_tmps = 0;
!   int offset = 0;
!   int i, num_tmps;
!   rtx xops[3];
! 
!   if (GET_CODE (dest) == MEM
!       && GET_CODE (XEXP (dest, 0)) == PRE_INC
!       && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
!     return output_move_pushmem (operands, insn, length, tmp_start, n_operands);
! 
!   if (!offsettable_memref_p (src))
!     fatal_insn ("Source is not offsettable", insn);
! 
!   if (!offsettable_memref_p (dest))
!     fatal_insn ("Destination is not offsettable", insn);
! 
!   /* Figure out which temporary registers we have available */
!   for (i = tmp_start; i < n_operands; i++)
!     {
!       if (GET_CODE (operands[i]) == REG)
! 	{
! 	  if ((length & 1) != 0 && !qi_tmp && QI_REG_P (operands[i]))
! 	    qi_tmp = operands[i];
! 
! 	  if (reg_overlap_mentioned_p (operands[i], dest))
! 	    fatal_insn ("Temporary register overlaps the destination", insn);
! 
! 	  if (reg_overlap_mentioned_p (operands[i], src))
! 	    fatal_insn ("Temporary register overlaps the source", insn);
! 
! 	  tmp_info[ max_tmps++ ].xops[2] = operands[i];
! 	  if (max_tmps == MAX_TMPS)
! 	    break;
! 	}
!     }
! 
!   if (max_tmps == 0)
!     fatal_insn ("No scratch registers were found to do memory->memory moves", insn);
! 
!   if ((length & 1) != 0)
!     {
!       if (!qi_tmp)
! 	fatal_insn ("No byte register found when moving odd # of bytes.", insn);
!     }
! 
!   while (length > 1)
!     {
!       for (num_tmps = 0; num_tmps < max_tmps; num_tmps++)
! 	{
! 	  if (length >= 4)
! 	    {
! 	      tmp_info[num_tmps].load    = AS2(mov%L0,%1,%2);
! 	      tmp_info[num_tmps].store   = AS2(mov%L0,%2,%0);
! 	      tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
! 	      tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
! 	      offset += 4;
! 	      length -= 4;
! 	    }
! 	  else if (length >= 2)
! 	    {
! 	      tmp_info[num_tmps].load    = AS2(mov%W0,%1,%2);
! 	      tmp_info[num_tmps].store   = AS2(mov%W0,%2,%0);
! 	      tmp_info[num_tmps].xops[0] = adj_offsettable_operand (dest, offset);
! 	      tmp_info[num_tmps].xops[1] = adj_offsettable_operand (src, offset);
! 	      offset += 2;
! 	      length -= 2;
! 	    }
! 	  else
! 	    break;
! 	}
! 
!       for (i = 0; i < num_tmps; i++)
! 	output_asm_insn (tmp_info[i].load, tmp_info[i].xops);
! 
!       for (i = 0; i < num_tmps; i++)
! 	output_asm_insn (tmp_info[i].store, tmp_info[i].xops);
!     }
! 
!   if (length == 1)
!     {
!       xops[0] = adj_offsettable_operand (dest, offset);
!       xops[1] = adj_offsettable_operand (src, offset);
!       xops[2] = qi_tmp;
!       output_asm_insn (AS2(mov%B0,%1,%2), xops);
!       output_asm_insn (AS2(mov%B0,%2,%0), xops);
!     }
! 
!   return "";
! }
! 
! 
! int
! standard_80387_constant_p (x)
!      rtx x;
! {
! #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
!   REAL_VALUE_TYPE d;
!   jmp_buf handler;
!   int is0, is1;
! 
!   if (setjmp (handler))
!     return 0;
! 
!   set_float_handler (handler);
!   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
!   is0 = REAL_VALUES_EQUAL (d, dconst0);
!   is1 = REAL_VALUES_EQUAL (d, dconst1);
!   set_float_handler (NULL_PTR);
! 
!   if (is0)
!     return 1;
! 
!   if (is1)
!     return 2;
! 
!   /* Note that on the 80387, other constants, such as pi,
!      are much slower to load as standard constants
!      than to load from doubles in memory!  */
! #endif
! 
!   return 0;
! }
! 
! char *
! output_move_const_single (operands)
!      rtx *operands;
! {
!   if (FP_REG_P (operands[0]))
!     {
!       int conval = standard_80387_constant_p (operands[1]);
! 
!       if (conval == 1)
! 	return "fldz";
! 
!       if (conval == 2)
! 	return "fld1";
!     }
!   if (GET_CODE (operands[1]) == CONST_DOUBLE)
!     {
!       REAL_VALUE_TYPE r; long l;
! 
!       if (GET_MODE (operands[1]) == XFmode)
! 	abort ();
! 
!       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
!       REAL_VALUE_TO_TARGET_SINGLE (r, l);
!       operands[1] = GEN_INT (l);
!     }
!   return singlemove_string (operands);
! }
! 
! /* Returns 1 if OP is either a symbol reference or a sum of a symbol
!    reference and a constant.  */
  
  int
  symbolic_operand (op, mode)
--- 946,1014 ----
  
    return "";
  }
  
! int
! standard_80387_constant_p (x)
!      rtx x;
  {
+ #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
+   REAL_VALUE_TYPE d;
+   jmp_buf handler;
+   int is0, is1;
  
!   if (setjmp (handler))
!     return 0;
  
!   set_float_handler (handler);
!   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
!   is0 = REAL_VALUES_EQUAL (d, dconst0);
!   is1 = REAL_VALUES_EQUAL (d, dconst1);
!   set_float_handler (NULL_PTR);
  
!   if (is0)
!     return 1;
  
!   if (is1)
!     return 2;
  
!   /* Note that on the 80387, other constants, such as pi,
!      are much slower to load as standard constants
!      than to load from doubles in memory!  */
! #endif
  
!   return 0;
! }
  
! char *
! output_move_const_single (operands)
!      rtx *operands;
! {
!   if (FP_REG_P (operands[0]))
!     {
!       int conval = standard_80387_constant_p (operands[1]);
  
!       if (conval == 1)
! 	return "fldz";
  
!       if (conval == 2)
! 	return "fld1";
!     }
!   if (GET_CODE (operands[1]) == CONST_DOUBLE)
!     {
!       REAL_VALUE_TYPE r; long l;
  
!       if (GET_MODE (operands[1]) == XFmode)
! 	abort ();
  
!       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
!       REAL_VALUE_TO_TARGET_SINGLE (r, l);
!       operands[1] = GEN_INT (l);
!     }
!   return singlemove_string (operands);
  }
  
! /* Returns 1 if OP is either a symbol reference or a sum of a symbol
!    reference and a constant.  */
  
  int
  symbolic_operand (op, mode)
***************
*** 1447,1452 ****
--- 1119,1229 ----
    return 0;
  }
  
+ /* Return a legitimate reference for ORIG (an address) using the
+    register REG.  If REG is 0, a new pseudo is generated.
+ 
+    There are three types of references that must be handled:
+ 
+    1. Global data references must load the address from the GOT, via
+       the PIC reg.  An insn is emitted to do this load, and the reg is
+       returned.
+ 
+    2. Static data references must compute the address as an offset
+       from the GOT, whose base is in the PIC reg.  An insn is emitted to
+       compute the address into a reg, and the reg is returned.  Static
+       data objects have SYMBOL_REF_FLAG set to differentiate them from
+       global data objects.
+ 
+    3. Constant pool addresses must be handled special.  They are
+       considered legitimate addresses, but only if not used with regs.
+       When printed, the output routines know to print the reference with the
+       PIC reg, even though the PIC reg doesn't appear in the RTL.
+ 
+    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
+    reg also appears in the address (except for constant pool references,
+    noted above).
+ 
+    "switch" statements also require special handling when generating
+    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
+ 
+ rtx
+ legitimize_pic_address (orig, reg)
+      rtx orig;
+      rtx reg;
+ {
+   rtx addr = orig;
+   rtx new = orig;
+ 
+   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
+     {
+       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
+ 	reg = new = orig;
+       else
+ 	{
+ 	  if (reg == 0)
+ 	    reg = gen_reg_rtx (Pmode);
+ 
+ 	  if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
+ 	    new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
+ 	  else
+ 	    new = gen_rtx (MEM, Pmode,
+ 			   gen_rtx (PLUS, Pmode,
+ 				    pic_offset_table_rtx, orig));
+ 
+ 	  emit_move_insn (reg, new);
+ 	}
+       current_function_uses_pic_offset_table = 1;
+       return reg;
+     }
+   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
+     {
+       rtx base;
+ 
+       if (GET_CODE (addr) == CONST)
+ 	{
+ 	  addr = XEXP (addr, 0);
+ 	  if (GET_CODE (addr) != PLUS)
+ 	    abort ();
+ 	}
+ 
+       if (XEXP (addr, 0) == pic_offset_table_rtx)
+ 	return orig;
+ 
+       if (reg == 0)
+ 	reg = gen_reg_rtx (Pmode);
+ 
+       base = legitimize_pic_address (XEXP (addr, 0), reg);
+       addr = legitimize_pic_address (XEXP (addr, 1),
+ 				     base == reg ? NULL_RTX : reg);
+ 
+       if (GET_CODE (addr) == CONST_INT)
+ 	return plus_constant (base, INTVAL (addr));
+ 
+       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
+ 	{
+ 	  base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
+ 	  addr = XEXP (addr, 1);
+ 	}
+ 	return gen_rtx (PLUS, Pmode, base, addr);
+     }
+   return new;
+ }
+ 
+ /* Emit insns to move operands[1] into operands[0].  */
+ 
+ void
+ emit_pic_move (operands, mode)
+      rtx *operands;
+      enum machine_mode mode;
+ {
+   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
+ 
+   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
+     operands[1] = (rtx) force_reg (SImode, operands[1]);
+   else
+     operands[1] = legitimize_pic_address (operands[1], temp);
+ }
+ 
  /* This function generates the assembly code for function entry.
     FILE is an stdio stream to output the code to.
     SIZE is an int: how many units of temporary storage to allocate. */
***************
*** 1540,1546 ****
    return nregs == 0 || ! frame_pointer_needed;
  }
  
- 
  /* This function generates the assembly code for function exit.
     FILE is an stdio stream to output the code to.
     SIZE is an int: how many units of temporary storage to deallocate. */
--- 1317,1322 ----
***************
*** 1614,1620 ****
      {
        /* On i486, mov & pop is faster than "leave". */
  
!       if (!TARGET_386)
  	{
  	  xops[0] = frame_pointer_rtx;
  	  output_asm_insn (AS2 (mov%L2,%0,%2), xops);
--- 1390,1396 ----
      {
        /* On i486, mov & pop is faster than "leave". */
  
!       if (TARGET_486)
  	{
  	  xops[0] = frame_pointer_rtx;
  	  output_asm_insn (AS2 (mov%L2,%0,%2), xops);
***************
*** 1653,3245 ****
    else
      output_asm_insn ("ret", xops);
  }
- 
  
! /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
!    that is a valid memory address for an instruction.
!    The MODE argument is the machine mode for the MEM expression
!    that wants to use this address.
! 
!    On x86, legitimate addresses are:
! 	base				movl (base),reg
! 	displacement			movl disp,reg
! 	base + displacement		movl disp(base),reg
! 	index + base			movl (base,index),reg
! 	(index + base) + displacement	movl disp(base,index),reg
! 	index*scale			movl (,index,scale),reg
! 	index*scale + disp		movl disp(,index,scale),reg
! 	index*scale + base 		movl (base,index,scale),reg
! 	(index*scale + base) + disp	movl disp(base,index,scale),reg
! 
! 	In each case, scale can be 1, 2, 4, 8.  */
! 
! /* This is exactly the same as print_operand_addr, except that
!    it recognizes addresses instead of printing them.
! 
!    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
!    convert common non-canonical forms to canonical form so that they will
!    be recognized.  */
! 
! #define ADDR_INVALID(msg,insn)						\
! do {									\
!   if (TARGET_DEBUG_ADDR)						\
!     {									\
!       fprintf (stderr, msg);						\
!       debug_rtx (insn);							\
!     }									\
! } while (0)
  
! int
! legitimate_address_p (mode, addr, strict)
!      enum machine_mode mode;
!      register rtx addr;
!      int strict;
  {
!   rtx base  = NULL_RTX;
!   rtx indx  = NULL_RTX;
!   rtx scale = NULL_RTX;
!   rtx disp  = NULL_RTX;
! 
!   if (TARGET_DEBUG_ADDR)
!     {
!       fprintf (stderr,
! 	       "\n==========\nGO_IF_LEGITIMATE_ADDRESS, mode = %s, strict = %d\n",
! 	       GET_MODE_NAME (mode), strict);
! 
!       debug_rtx (addr);
!     }
! 
!   if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
!       base = addr;				/* base reg */
  
!   else if (GET_CODE (addr) == PLUS)
      {
!       rtx op0 = XEXP (addr, 0);
!       rtx op1 = XEXP (addr, 1);
!       enum rtx_code code0 = GET_CODE (op0);
!       enum rtx_code code1 = GET_CODE (op1);
  
!       if (code0 == REG || code0 == SUBREG)
  	{
! 	  if (code1 == REG || code1 == SUBREG)
! 	    {
! 	      indx = op0;			/* index + base */
! 	      base = op1;
! 	    }
! 
! 	  else
! 	    {
! 	      base = op0;			/* base + displacement */
! 	      disp = op1;
! 	    }
! 	}
! 
!       else if (code0 == MULT)
! 	{
! 	  indx  = XEXP (op0, 0);
! 	  scale = XEXP (op0, 1);
! 
! 	  if (code1 == REG || code1 == SUBREG)
! 	    base = op1;				/* index*scale + base */
! 
! 	  else
! 	    disp = op1;				/* index*scale + disp */
! 	}
! 
!       else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
! 	{
! 	  indx  = XEXP (XEXP (op0, 0), 0);	/* index*scale + base + disp */
! 	  scale = XEXP (XEXP (op0, 0), 1);
! 	  base  = XEXP (op0, 1);
! 	  disp  = op1;
! 	}
! 
!       else if (code0 == PLUS)
! 	{
! 	  indx = XEXP (op0, 0);			/* index + base + disp */
! 	  base = XEXP (op0, 1);
! 	  disp = op1;
  	}
  
        else
! 	{
! 	  ADDR_INVALID ("PLUS subcode is not valid.\n", op0);
! 	  return FALSE;
! 	}
!     }
  
!   else if (GET_CODE (addr) == MULT)
!     {
!       indx  = XEXP (addr, 0);			/* index*scale */
!       scale = XEXP (addr, 1);
!     }
  
!   else
!     disp = addr;				/* displacement */
  
!   /* Allow arg pointer and stack pointer as index if there is not scaling */
!   if (base && indx && !scale
!       && (indx == arg_pointer_rtx || indx == stack_pointer_rtx))
!     {
!       rtx tmp = base;
!       base = indx;
!       indx = tmp;
!     }
  
!   /* Validate base register */
!   /* Don't allow SUBREG's here, it can lead to spill failures when the base
!      is one word out of a two word structure, which is represented internally
!      as a DImode int.  */
!   if (base)
!     {
!       if (GET_CODE (base) != REG)
! 	{
! 	  ADDR_INVALID ("Base is not a register.\n", base);
! 	  return FALSE;
! 	}
  
!       if ((strict && !REG_OK_FOR_BASE_STRICT_P (base))
! 	  || (!strict && !REG_OK_FOR_BASE_NONSTRICT_P (base)))
  	{
! 	  ADDR_INVALID ("Base is not valid.\n", base);
! 	  return FALSE;
  	}
!     }
  
!   /* Validate index register */
!   /* Don't allow SUBREG's here, it can lead to spill failures when the index
!      is one word out of a two word structure, which is represented internally
!      as a DImode int.  */
!   if (indx)
!     {
!       if (GET_CODE (indx) != REG)
  	{
! 	  ADDR_INVALID ("Index is not a register.\n", indx);
! 	  return FALSE;
  	}
! 
!       if ((strict && !REG_OK_FOR_INDEX_STRICT_P (indx))
! 	  || (!strict && !REG_OK_FOR_INDEX_NONSTRICT_P (indx)))
  	{
! 	  ADDR_INVALID ("Index is not valid.\n", indx);
! 	  return FALSE;
  	}
!     }
!   else if (scale)
!     abort ();					/* scale w/o index invalid */
! 
!   /* Validate scale factor */
!   if (scale)
!     {
!       HOST_WIDE_INT value;
  
!       if (GET_CODE (scale) != CONST_INT)
! 	{
! 	  ADDR_INVALID ("Scale is not valid.\n", scale);
! 	  return FALSE;
! 	}
  
!       value = INTVAL (scale);
!       if (value != 1 && value != 2 && value != 4 && value != 8)
! 	{
! 	  ADDR_INVALID ("Scale is not a good multiplier.\n", scale);
! 	  return FALSE;
! 	}
      }
  
!   /* Validate displacement */
!   if (disp)
      {
!       if (!CONSTANT_ADDRESS_P (disp))
  	{
! 	  ADDR_INVALID ("Displacement is not valid.\n", disp);
! 	  return FALSE;
! 	}
  
!       if (GET_CODE (disp) == CONST_DOUBLE)
! 	{
! 	  ADDR_INVALID ("Displacement is a const_double.\n", disp);
! 	  return FALSE;
! 	}
  
!       if (flag_pic && SYMBOLIC_CONST (disp) && base != pic_offset_table_rtx
! 	  && (indx != pic_offset_table_rtx || scale != NULL_RTX))
! 	{
! 	  ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp);
! 	  return FALSE;
! 	}
  
!       if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp)
! 	  && (base != NULL_RTX || indx != NULL_RTX))
! 	{
! 	  ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", disp);
! 	  return FALSE;
! 	}
!     }
  
!   if (TARGET_DEBUG_ADDR)
!     fprintf (stderr, "Address is valid.\n");
  
!   /* Everything looks valid, return true */
!   return TRUE;
! }
  
! 
! /* Return a legitimate reference for ORIG (an address) using the
!    register REG.  If REG is 0, a new pseudo is generated.
  
!    There are three types of references that must be handled:
  
!    1. Global data references must load the address from the GOT, via
!       the PIC reg.  An insn is emitted to do this load, and the reg is
!       returned.
  
!    2. Static data references must compute the address as an offset
!       from the GOT, whose base is in the PIC reg.  An insn is emitted to
!       compute the address into a reg, and the reg is returned.  Static
!       data objects have SYMBOL_REF_FLAG set to differentiate them from
!       global data objects.
  
!    3. Constant pool addresses must be handled special.  They are
!       considered legitimate addresses, but only if not used with regs.
!       When printed, the output routines know to print the reference with the
!       PIC reg, even though the PIC reg doesn't appear in the RTL.
  
!    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
!    reg also appears in the address (except for constant pool references,
!    noted above).
  
!    "switch" statements also require special handling when generating
!    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
  
! rtx
! legitimize_pic_address (orig, reg)
!      rtx orig;
!      rtx reg;
! {
!   rtx addr = orig;
!   rtx new = orig;
  
!   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
!     {
!       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
! 	reg = new = orig;
!       else
! 	{
! 	  if (reg == 0)
! 	    reg = gen_reg_rtx (Pmode);
  
! 	  if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
! 	      || GET_CODE (addr) == LABEL_REF)
! 	    new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
! 	  else
! 	    new = gen_rtx (MEM, Pmode,
! 			   gen_rtx (PLUS, Pmode,
! 				    pic_offset_table_rtx, orig));
  
! 	  emit_move_insn (reg, new);
! 	}
!       current_function_uses_pic_offset_table = 1;
!       return reg;
!     }
!   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
!     {
!       rtx base;
  
!       if (GET_CODE (addr) == CONST)
! 	{
! 	  addr = XEXP (addr, 0);
! 	  if (GET_CODE (addr) != PLUS)
! 	    abort ();
! 	}
  
!       if (XEXP (addr, 0) == pic_offset_table_rtx)
! 	return orig;
  
!       if (reg == 0)
! 	reg = gen_reg_rtx (Pmode);
! 
!       base = legitimize_pic_address (XEXP (addr, 0), reg);
!       addr = legitimize_pic_address (XEXP (addr, 1),
! 				     base == reg ? NULL_RTX : reg);
! 
!       if (GET_CODE (addr) == CONST_INT)
! 	return plus_constant (base, INTVAL (addr));
! 
!       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
  	{
! 	  base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
! 	  addr = XEXP (addr, 1);
  	}
! 	return gen_rtx (PLUS, Pmode, base, addr);
      }
-   return new;
  }
  
! 
! /* Emit insns to move operands[1] into operands[0].  */
  
  void
! emit_pic_move (operands, mode)
!      rtx *operands;
!      enum machine_mode mode;
! {
!   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
! 
!   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
!     operands[1] = (rtx) force_reg (SImode, operands[1]);
!   else
!     operands[1] = legitimize_pic_address (operands[1], temp);
! }
! 
! 
! /* Try machine-dependent ways of modifying an illegitimate address
!    to be legitimate.  If we find one, return the new, valid address.
!    This macro is used in only one place: `memory_address' in explow.c.
! 
!    OLDX is the address as it was before break_out_memory_refs was called.
!    In some cases it is useful to look at this to decide what needs to be done.
! 
!    MODE and WIN are passed so that this macro can use
!    GO_IF_LEGITIMATE_ADDRESS.
! 
!    It is always safe for this macro to do nothing.  It exists to recognize
!    opportunities to optimize the output.
! 
!    For the 80386, we handle X+REG by loading X into a register R and
!    using R+REG.  R will go in a general reg and indexing will be used.
!    However, if REG is a broken-out memory address or multiplication,
!    nothing needs to be done because REG can certainly go in a general reg.
! 
!    When -fpic is used, special handling is needed for symbolic references.
!    See comments by legitimize_pic_address in i386.c for details.  */
! 
! rtx
! legitimize_address (x, oldx, mode)
!      register rtx x;
!      register rtx oldx;
!      enum machine_mode mode;
  {
!   int changed = 0;
!   unsigned log;
! 
!   if (TARGET_DEBUG_ADDR)
!     {
!       fprintf (stderr, "\n==========\nLEGITIMIZE_ADDRESS, mode = %s\n", GET_MODE_NAME (mode));
!       debug_rtx (x);
!     }
! 
!   if (flag_pic && SYMBOLIC_CONST (x))
!     return legitimize_pic_address (x, 0);
  
!   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
!   if (GET_CODE (x) == ASHIFT
!       && GET_CODE (XEXP (x, 1)) == CONST_INT
!       && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4)
      {
!       changed = 1;
!       x = gen_rtx (MULT, Pmode,
! 		   force_reg (Pmode, XEXP (x, 0)),
! 		   GEN_INT (1 << log));
!     }
  
!   if (GET_CODE (x) == PLUS)
!     {
!       /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
!       if (GET_CODE (XEXP (x, 0)) == ASHIFT
! 	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
! 	  && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 0), 1)))) < 4)
  	{
! 	  changed = 1;
! 	  XEXP (x, 0) = gen_rtx (MULT, Pmode,
! 				 force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
! 				 GEN_INT (1 << log));
  	}
! 
!       if (GET_CODE (XEXP (x, 1)) == ASHIFT
! 	  && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
! 	  && (log = (unsigned)exact_log2 (INTVAL (XEXP (XEXP (x, 1), 1)))) < 4)
  	{
! 	  changed = 1;
! 	  XEXP (x, 1) = gen_rtx (MULT, Pmode,
! 				 force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
! 				 GEN_INT (1 << log));
  	}
! 
!       /* Put multiply first if it isn't already */
!       if (GET_CODE (XEXP (x, 1)) == MULT)
  	{
! 	  rtx tmp = XEXP (x, 0);
! 	  XEXP (x, 0) = XEXP (x, 1);
! 	  XEXP (x, 1) = tmp;
! 	  changed = 1;
  	}
! 
!       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
! 	 into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
! 	 created by virtual register instantiation, register elimination, and
! 	 similar optimizations.  */
!       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
  	{
! 	  changed = 1;
! 	  x = gen_rtx (PLUS, Pmode,
! 		       gen_rtx (PLUS, Pmode, XEXP (x, 0), XEXP (XEXP (x, 1), 0)),
! 		       XEXP (XEXP (x, 1), 1));
  	}
  
!       /* Canonicalize (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
! 	 into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
!       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
! 	       && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
! 	       && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
! 	       && CONSTANT_P (XEXP (x, 1)))
  	{
! 	  rtx constant, other;
  
! 	  if (GET_CODE (XEXP (x, 1)) == CONST_INT)
! 	    {
! 	      constant = XEXP (x, 1);
! 	      other = XEXP (XEXP (XEXP (x, 0), 1), 1);
! 	    }
! 	  else if (GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 1)) == CONST_INT)
  	    {
! 	      constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
! 	      other = XEXP (x, 1);
  	    }
- 	  else
- 	    constant = 0;
  
! 	  if (constant)
  	    {
! 	      changed = 1;
! 	      x = gen_rtx (PLUS, Pmode,
! 			   gen_rtx (PLUS, Pmode, XEXP (XEXP (x, 0), 0),
! 				    XEXP (XEXP (XEXP (x, 0), 1), 0)),
! 			   plus_constant (other, INTVAL (constant)));
  	    }
- 	}
- 
-       if (changed && legitimate_address_p (mode, x, FALSE))
- 	return x;
  
!       if (GET_CODE (XEXP (x, 0)) == MULT)
! 	{
! 	  changed = 1;
! 	  XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
! 	}
  
!       if (GET_CODE (XEXP (x, 1)) == MULT)
! 	{
! 	  changed = 1;
! 	  XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
! 	}
  
!       if (changed
! 	  && GET_CODE (XEXP (x, 1)) == REG
! 	  && GET_CODE (XEXP (x, 0)) == REG)
! 	return x;
  
!       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
! 	{
! 	  changed = 1;
! 	  x = legitimize_pic_address (x, 0);
  	}
  
!       if (changed && legitimate_address_p (mode, x, FALSE))
! 	return x;
! 
!       if (GET_CODE (XEXP (x, 0)) == REG)
! 	{
! 	  register rtx temp = gen_reg_rtx (Pmode);
! 	  register rtx val  = force_operand (XEXP (x, 1), temp);
! 	  if (val != temp)
! 	    emit_move_insn (temp, val);
! 
! 	  XEXP (x, 1) = temp;
! 	  return x;
! 	}
  
!       else if (GET_CODE (XEXP (x, 1)) == REG)
  	{
! 	  register rtx temp = gen_reg_rtx (Pmode);
! 	  register rtx val  = force_operand (XEXP (x, 0), temp);
! 	  if (val != temp)
! 	    emit_move_insn (temp, val);
! 
! 	  XEXP (x, 0) = temp;
! 	  return x;
  	}
      }
- 
-   return x;
  }
- 
  
! /* Print an integer constant expression in assembler syntax.  Addition
!    and subtraction are the only arithmetic that may appear in these
!    expressions.  FILE is the stdio stream to write to, X is the rtx, and
!    CODE is the operand print code from the output string.  */
  
! static void
! output_pic_addr_const (file, x, code)
!      FILE *file;
!      rtx x;
!      int code;
! {
!   char buf[256];
  
!   switch (GET_CODE (x))
      {
!     case PC:
!       if (flag_pic)
! 	putc ('.', file);
!       else
! 	abort ();
!       break;
! 
!     case SYMBOL_REF:
!     case LABEL_REF:
!       if (GET_CODE (x) == SYMBOL_REF)
! 	assemble_name (file, XSTR (x, 0));
!       else
  	{
! 	  ASM_GENERATE_INTERNAL_LABEL (buf, "L",
! 				       CODE_LABEL_NUMBER (XEXP (x, 0)));
! 	  assemble_name (asm_out_file, buf);
  	}
  
!       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
! 	fprintf (file, "@GOTOFF(%%ebx)");
!       else if (code == 'P')
! 	fprintf (file, "@PLT");
!       else if (GET_CODE (x) == LABEL_REF)
! 	fprintf (file, "@GOTOFF");
!       else if (! SYMBOL_REF_FLAG (x))
! 	fprintf (file, "@GOT");
!       else
! 	fprintf (file, "@GOTOFF");
! 
!       break;
! 
!     case CODE_LABEL:
!       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
!       assemble_name (asm_out_file, buf);
!       break;
! 
!     case CONST_INT:
!       fprintf (file, "%d", INTVAL (x));
!       break;
! 
!     case CONST:
!       /* This used to output parentheses around the expression,
! 	 but that does not work on the 386 (either ATT or BSD assembler).  */
!       output_pic_addr_const (file, XEXP (x, 0), code);
!       break;
  
!     case CONST_DOUBLE:
!       if (GET_MODE (x) == VOIDmode)
  	{
! 	  /* We can use %d if the number is <32 bits and positive.  */
! 	  if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
! 	    fprintf (file, "0x%x%08x",
! 		     CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
  	  else
! 	    fprintf (file, "%d", CONST_DOUBLE_LOW (x));
  	}
!       else
! 	/* We can't handle floating point constants;
! 	   PRINT_OPERAND must handle them.  */
! 	output_operand_lossage ("floating constant misused");
!       break;
  
!     case PLUS:
!       /* Some assemblers need integer constants to appear last (eg masm).  */
!       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  output_pic_addr_const (file, XEXP (x, 1), code);
! 	  if (INTVAL (XEXP (x, 0)) >= 0)
! 	    fprintf (file, "+");
! 	  output_pic_addr_const (file, XEXP (x, 0), code);
  	}
!       else
  	{
! 	  output_pic_addr_const (file, XEXP (x, 0), code);
! 	  if (INTVAL (XEXP (x, 1)) >= 0)
! 	    fprintf (file, "+");
! 	  output_pic_addr_const (file, XEXP (x, 1), code);
  	}
!       break;
  
      case MINUS:
!       output_pic_addr_const (file, XEXP (x, 0), code);
!       fprintf (file, "-");
!       output_pic_addr_const (file, XEXP (x, 1), code);
!       break;
  
      default:
!       output_operand_lossage ("invalid expression as operand");
      }
  }
- 
- /* Meaning of CODE:
-    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
-    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
-    R -- print the prefix for register names.
-    z -- print the opcode suffix for the size of the current operand.
-    * -- print a star (in certain assembler syntax)
-    w -- print the operand as if it's a "word" (HImode) even if it isn't.
-    c -- don't print special prefixes before constant operands.
-    J -- print the appropriate jump operand.
- */
  
! void
! print_operand (file, x, code)
!      FILE *file;
!      rtx x;
!      int code;
  {
!   if (code)
      {
!       switch (code)
! 	{
! 	case '*':
! 	  if (USE_STAR)
! 	    putc ('*', file);
! 	  return;
  
! 	case 'L':
! 	  PUT_OP_SIZE (code, 'l', file);
! 	  return;
  
! 	case 'W':
! 	  PUT_OP_SIZE (code, 'w', file);
! 	  return;
  
! 	case 'B':
! 	  PUT_OP_SIZE (code, 'b', file);
! 	  return;
  
! 	case 'Q':
! 	  PUT_OP_SIZE (code, 'l', file);
! 	  return;
! 
! 	case 'S':
! 	  PUT_OP_SIZE (code, 's', file);
! 	  return;
  
! 	case 'T':
! 	  PUT_OP_SIZE (code, 't', file);
! 	  return;
  
! 	case 'z':
! 	  /* 387 opcodes don't get size suffixes if the operands are
! 	     registers. */
  
! 	  if (STACK_REG_P (x))
! 	    return;
  
! 	  /* this is the size of op from size of operand */
! 	  switch (GET_MODE_SIZE (GET_MODE (x)))
! 	    {
! 	    case 1:
! 	      PUT_OP_SIZE ('B', 'b', file);
! 	      return;
  
! 	    case 2:
! 	      PUT_OP_SIZE ('W', 'w', file);
! 	      return;
  
! 	    case 4:
! 	      if (GET_MODE (x) == SFmode)
! 		{
! 		  PUT_OP_SIZE ('S', 's', file);
! 		  return;
! 		}
! 	      else
! 		PUT_OP_SIZE ('L', 'l', file);
! 	      return;
  
! 	    case 12:
! 		  PUT_OP_SIZE ('T', 't', file);
! 		  return;
  
! 	    case 8:
! 	      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
! 		{
! #ifdef GAS_MNEMONICS
! 		  PUT_OP_SIZE ('Q', 'q', file);
! 		  return;
! #else
! 		  PUT_OP_SIZE ('Q', 'l', file);	/* Fall through */
! #endif
! 		}
  
! 	      PUT_OP_SIZE ('Q', 'l', file);
! 	      return;
! 	    }
  
! 	case 'b':
! 	case 'w':
! 	case 'k':
! 	case 'h':
! 	case 'y':
! 	case 'P':
! 	  break;
  
! 	case 'J':
! 	  switch (GET_CODE (x))
! 	    {
! 	      /* These conditions are appropriate for testing the result
! 		 of an arithmetic operation, not for a compare operation.
! 	         Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
! 		 CC_Z_IN_NOT_C false and not floating point.  */
! 	    case NE:  fputs ("jne", file); return;
! 	    case EQ:  fputs ("je",  file); return;
! 	    case GE:  fputs ("jns", file); return;
! 	    case LT:  fputs ("js",  file); return;
! 	    case GEU: fputs ("jmp", file); return;
! 	    case GTU: fputs ("jne",  file); return;
! 	    case LEU: fputs ("je", file); return;
! 	    case LTU: fputs ("#branch never",  file); return;
  
! 	    /* no matching branches for GT nor LE */
! 	    }
! 	  abort ();
  
! 	default:
! 	  {
! 	    char str[50];
  
! 	    sprintf (str, "invalid operand code `%c'", code);
! 	    output_operand_lossage (str);
! 	  }
! 	}
!     }
!   if (GET_CODE (x) == REG)
!     {
!       PRINT_REG (x, code, file);
!     }
!   else if (GET_CODE (x) == MEM)
!     {
!       PRINT_PTR (x, file);
!       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
! 	{
! 	  if (flag_pic)
! 	    output_pic_addr_const (file, XEXP (x, 0), code);
! 	  else
! 	    output_addr_const (file, XEXP (x, 0));
! 	}
!       else
! 	output_address (XEXP (x, 0));
!     }
!   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
!     {
!       REAL_VALUE_TYPE r; long l;
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_TARGET_SINGLE (r, l);
!       PRINT_IMMED_PREFIX (file);
!       fprintf (file, "0x%x", l);
!     }
!  /* These float cases don't actually occur as immediate operands. */
!  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
!     {
!       REAL_VALUE_TYPE r; char dstr[30];
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
!       fprintf (file, "%s", dstr);
!     }
!   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
!     {
!       REAL_VALUE_TYPE r; char dstr[30];
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
!       fprintf (file, "%s", dstr);
!     }
!   else 
      {
!       if (code != 'P')
  	{
! 	  if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
! 	    PRINT_IMMED_PREFIX (file);
! 	  else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
! 		   || GET_CODE (x) == LABEL_REF)
! 	    PRINT_OFFSET_PREFIX (file);
  	}
-       if (flag_pic)
- 	output_pic_addr_const (file, x, code);
-       else
- 	output_addr_const (file, x);
-     }
- }
- 
- /* Print a memory operand whose address is ADDR.  */
- 
- void
- print_operand_address (file, addr)
-      FILE *file;
-      register rtx addr;
- {
-   register rtx reg1, reg2, breg, ireg;
-   rtx offset;
  
!   switch (GET_CODE (addr))
!     {
!     case REG:
!       ADDR_BEG (file);
!       fprintf (file, "%se", RP);
!       fputs (hi_reg_name[REGNO (addr)], file);
!       ADDR_END (file);
!       break;
  
!     case PLUS:
!       reg1 = 0;
!       reg2 = 0;
!       ireg = 0;
!       breg = 0;
!       offset = 0;
!       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
  	{
! 	  offset = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
  	}
!       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
  	{
! 	  offset = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
  	}
!       if (GET_CODE (addr) != PLUS) ;
!       else if (GET_CODE (XEXP (addr, 0)) == MULT)
! 	{
! 	  reg1 = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
! 	}
!       else if (GET_CODE (XEXP (addr, 1)) == MULT)
! 	{
! 	  reg1 = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
! 	}
!       else if (GET_CODE (XEXP (addr, 0)) == REG)
! 	{
! 	  reg1 = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
! 	}
!       else if (GET_CODE (XEXP (addr, 1)) == REG)
! 	{
! 	  reg1 = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
! 	}
!       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
! 	{
! 	  if (reg1 == 0) reg1 = addr;
! 	  else reg2 = addr;
! 	  addr = 0;
! 	}
!       if (offset != 0)
  	{
! 	  if (addr != 0) abort ();
! 	  addr = offset;
  	}
!       if ((reg1 && GET_CODE (reg1) == MULT)
! 	  || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
  	{
! 	  breg = reg2;
! 	  ireg = reg1;
  	}
!       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
  	{
! 	  breg = reg1;
! 	  ireg = reg2;
  	}
  
!       if (ireg != 0 || breg != 0)
! 	{
! 	  int scale = 1;
  
! 	  if (addr != 0)
! 	    {
! 	      if (flag_pic)
! 		output_pic_addr_const (file, addr, 0);
  
! 	      else if (GET_CODE (addr) == LABEL_REF)
! 		output_asm_label (addr);
  
! 	      else
! 		output_addr_const (file, addr);
! 	    }
  
!   	  if (ireg != 0 && GET_CODE (ireg) == MULT)
! 	    {
! 	      scale = INTVAL (XEXP (ireg, 1));
! 	      ireg = XEXP (ireg, 0);
! 	    }
  
! 	  /* The stack pointer can only appear as a base register,
! 	     never an index register, so exchange the regs if it is wrong. */
  
! 	  if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
! 	    {
! 	      rtx tmp;
  
! 	      tmp = breg;
! 	      breg = ireg;
! 	      ireg = tmp;
! 	    }
  
! 	  /* output breg+ireg*scale */
! 	  PRINT_B_I_S (breg, ireg, scale, file);
! 	  break;
! 	}
  
!     case MULT:
!       {
! 	int scale;
! 	if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
! 	  {
! 	    scale = INTVAL (XEXP (addr, 0));
! 	    ireg = XEXP (addr, 1);
! 	  }
! 	else
! 	  {
! 	    scale = INTVAL (XEXP (addr, 1));
! 	    ireg = XEXP (addr, 0);
! 	  }
! 	output_addr_const (file, const0_rtx);
! 	PRINT_B_I_S ((rtx) 0, ireg, scale, file);
!       }
!       break;
  
!     default:
!       if (GET_CODE (addr) == CONST_INT
! 	  && INTVAL (addr) < 0x8000
! 	  && INTVAL (addr) >= -0x8000)
! 	fprintf (file, "%d", INTVAL (addr));
        else
! 	{
! 	  if (flag_pic)
! 	    output_pic_addr_const (file, addr, 0);
! 	  else
! 	    output_addr_const (file, addr);
! 	}
      }
  }
  
! /* Set the cc_status for the results of an insn whose pattern is EXP.
!    On the 80386, we assume that only test and compare insns, as well
!    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT,
!    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
!    Also, we assume that jumps, moves and sCOND don't affect the condition
!    codes.  All else clobbers the condition codes, by assumption.
  
!    We assume that ALL integer add, minus, etc. instructions effect the
!    condition codes.  This MUST be consistent with i386.md.
  
!    We don't record any float test or compare - the redundant test &
!    compare check in final.c does not handle stack-like regs correctly. */
  
! void
! notice_update_cc (exp)
!      rtx exp;
! {
!   if (GET_CODE (exp) == SET)
      {
!       /* Jumps do not alter the cc's.  */
!       if (SET_DEST (exp) == pc_rtx)
! 	return;
!       /* Moving register or memory into a register:
! 	 it doesn't alter the cc's, but it might invalidate
! 	 the RTX's which we remember the cc's came from.
! 	 (Note that moving a constant 0 or 1 MAY set the cc's).  */
!       if (REG_P (SET_DEST (exp))
! 	  && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
! 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
! 	{
! 	  if (cc_status.value1
! 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
! 	    cc_status.value1 = 0;
! 	  if (cc_status.value2
! 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
! 	    cc_status.value2 = 0;
! 	  return;
! 	}
!       /* Moving register into memory doesn't alter the cc's.
! 	 It may invalidate the RTX's which we remember the cc's came from.  */
!       if (GET_CODE (SET_DEST (exp)) == MEM
! 	  && (REG_P (SET_SRC (exp))
! 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
! 	{
! 	  if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
! 	    cc_status.value1 = 0;
! 	  if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
! 	    cc_status.value2 = 0;
! 	  return;
! 	}
!       /* Function calls clobber the cc's.  */
!       else if (GET_CODE (SET_SRC (exp)) == CALL)
! 	{
! 	  CC_STATUS_INIT;
! 	  return;
! 	}
!       /* Tests and compares set the cc's in predictable ways.  */
!       else if (SET_DEST (exp) == cc0_rtx)
! 	{
! 	  CC_STATUS_INIT;
! 	  cc_status.value1 = SET_SRC (exp);
! 	  return;
! 	}
!       /* Certain instructions effect the condition codes. */
!       else if (GET_MODE (SET_SRC (exp)) == SImode
! 	       || GET_MODE (SET_SRC (exp)) == HImode
! 	       || GET_MODE (SET_SRC (exp)) == QImode)
! 	switch (GET_CODE (SET_SRC (exp)))
! 	  {
! 	  case ASHIFTRT: case LSHIFTRT:
! 	  case ASHIFT:
! 	    /* Shifts on the 386 don't set the condition codes if the
! 	       shift count is zero. */
! 	    if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
! 	      {
! 		CC_STATUS_INIT;
! 		break;
! 	      }
! 	    /* We assume that the CONST_INT is non-zero (this rtx would
! 	       have been deleted if it were zero. */
  
! 	  case PLUS: case MINUS: case NEG:
! 	  case AND: case IOR: case XOR:
! 	    cc_status.flags = CC_NO_OVERFLOW;
! 	    cc_status.value1 = SET_SRC (exp);
! 	    cc_status.value2 = SET_DEST (exp);
! 	    break;
  
! 	  default:
! 	    CC_STATUS_INIT;
! 	  }
!       else
! 	{
! 	  CC_STATUS_INIT;
! 	}
      }
!   else if (GET_CODE (exp) == PARALLEL
! 	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
      {
!       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
! 	return;
!       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
! 	{
! 	  CC_STATUS_INIT;
! 	  if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
! 	    cc_status.flags |= CC_IN_80387;
! 	  else
! 	    cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
! 	  return;
! 	}
!       CC_STATUS_INIT;
      }
    else
      {
!       CC_STATUS_INIT;
      }
  }
- 
- /* Split one or more DImode RTL references into pairs of SImode
-    references.  The RTL can be REG, offsettable MEM, integer constant, or
-    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
-    split and "num" is its length.  lo_half and hi_half are output arrays
-    that parallel "operands". */
  
  void
! split_di (operands, num, lo_half, hi_half)
!      rtx operands[];
!      int num;
!      rtx lo_half[], hi_half[];
  {
!   while (num--)
!     {
!       if (GET_CODE (operands[num]) == REG)
! 	{
! 	  lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
! 	  hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
! 	}
!       else if (CONSTANT_P (operands[num]))
! 	{
! 	  split_double (operands[num], &lo_half[num], &hi_half[num]);
! 	}
!       else if (offsettable_memref_p (operands[num]))
! 	{
! 	  lo_half[num] = operands[num];
! 	  hi_half[num] = adj_offsettable_operand (operands[num], 4);
! 	}
!       else
! 	abort();
!     }
  }
- 
- /* Return 1 if this is a valid binary operation on a 387.
-    OP is the expression matched, and MODE is its mode. */
  
! int
! binary_387_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
  {
!   if (mode != VOIDmode && mode != GET_MODE (op))
!     return 0;
  
!   switch (GET_CODE (op))
!     {
!     case PLUS:
!     case MINUS:
!     case MULT:
!     case DIV:
!       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
  
!     default:
!       return 0;
!     }
  }
  
! 
! /* Return 1 if this is a valid shift or rotate operation on a 386.
!    OP is the expression matched, and MODE is its mode. */
  
! int
! shift_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
  {
!   rtx operand = XEXP (op, 0);
  
!   if (mode != VOIDmode && mode != GET_MODE (op))
!     return 0;
  
-   if (GET_MODE (operand) != GET_MODE (op)
-       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
-     return 0;
  
!   return (GET_CODE (op) == ASHIFT
! 	  || GET_CODE (op) == ASHIFTRT
! 	  || GET_CODE (op) == LSHIFTRT
! 	  || GET_CODE (op) == ROTATE
! 	  || GET_CODE (op) == ROTATERT);
  }
  
! /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
!    MODE is not used.  */
! 
! int
! VOIDmode_compare_op (op, mode)
      register rtx op;
      enum machine_mode mode;
  {
!   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
  }
- 
- /* Output code to perform a 387 binary operation in INSN, one of PLUS,
-    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
-    is the expression of the binary operation.  The output may either be
-    emitted here, or returned to the caller, like all output_* functions.
  
!    There is no guarantee that the operands are the same mode, as they
!    might be within FLOAT or FLOAT_EXTEND expressions. */
  
! char *
! output_387_binary_op (insn, operands)
!      rtx insn;
!      rtx *operands;
  {
!   rtx temp;
!   char *base_op;
!   static char buf[100];
  
!   switch (GET_CODE (operands[3]))
      {
!     case PLUS:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fiadd";
!       else
! 	base_op = "fadd";
!       break;
  
!     case MINUS:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fisub";
!       else
! 	base_op = "fsub";
        break;
  
!     case MULT:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fimul";
!       else
! 	base_op = "fmul";
!       break;
  
!     case DIV:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fidiv";
!       else
! 	base_op = "fdiv";
!       break;
  
!     default:
!       abort ();
      }
! 
!   strcpy (buf, base_op);
! 
!   switch (GET_CODE (operands[3]))
      {
!     case MULT:
!     case PLUS:
!       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  	{
! 	  temp = operands[2];
! 	  operands[2] = operands[1];
! 	  operands[1] = temp;
  	}
! 
!       if (GET_CODE (operands[2]) == MEM)
! 	return strcat (buf, AS1 (%z2,%2));
! 
!       if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
!       else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
- 
-       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
- 	return strcat (buf, AS2 (p,%2,%0));
- 
-       if (STACK_TOP_P (operands[0]))
- 	return strcat (buf, AS2C (%y2,%0));
        else
- 	return strcat (buf, AS2C (%2,%0));
- 
-     case MINUS:
-     case DIV:
-       if (GET_CODE (operands[1]) == MEM)
- 	return strcat (buf, AS1 (r%z1,%1));
- 
-       if (GET_CODE (operands[2]) == MEM)
- 	return strcat (buf, AS1 (%z2,%2));
- 
-       if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
! 	  RET;
  	}
!       else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
! 
!       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
! 	abort ();
! 
!       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
! 	return strcat (buf, AS2 (rp,%2,%0));
! 
!       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	return strcat (buf, AS2 (p,%1,%0));
! 
!       if (STACK_TOP_P (operands[0]))
  	{
! 	  if (STACK_TOP_P (operands[1]))
! 	    return strcat (buf, AS2C (%y2,%0));
  	  else
! 	    return strcat (buf, AS2 (r,%y1,%0));
  	}
!       else if (STACK_TOP_P (operands[1]))
! 	return strcat (buf, AS2C (%1,%0));
!       else
! 	return strcat (buf, AS2 (r,%2,%0));
! 
!     default:
!       abort ();
      }
  }
- 
- /* Output code for INSN to convert a float to a signed int.  OPERANDS
-    are the insn operands.  The output may be SFmode or DFmode and the
-    input operand may be SImode or DImode.  As a special case, make sure
-    that the 387 stack top dies if the output mode is DImode, because the
-    hardware requires this.  */
  
! char *
! output_fix_trunc (insn, operands)
!      rtx insn;
!      rtx *operands;
  {
!   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
!   rtx xops[2];
  
!   if (! STACK_TOP_P (operands[1]) ||
!       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
!     abort ();
! 
!   xops[0] = GEN_INT (12);
!   xops[1] = operands[4];
! 
!   output_asm_insn (AS1 (fnstc%W2,%2), operands);
!   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
!   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
!   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
!   output_asm_insn (AS1 (fldc%W3,%3), operands);
! 
!   if (NON_STACK_REG_P (operands[0]))
!     output_to_reg (operands[0], stack_top_dies);
!   else if (GET_CODE (operands[0]) == MEM)
      {
!       if (stack_top_dies)
! 	output_asm_insn (AS1 (fistp%z0,%0), operands);
        else
! 	output_asm_insn (AS1 (fist%z0,%0), operands);
      }
!   else
!     abort ();
! 
!   return AS1 (fldc%W2,%2);
  }
- 
- /* Output code for INSN to compare OPERANDS.  The two operands might
-    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
-    expression.  If the compare is in mode CCFPEQmode, use an opcode that
-    will not fault if a qNaN is present. */
  
! char *
! output_float_compare (insn, operands)
!      rtx insn;
!      rtx *operands;
  {
!   int stack_top_dies;
!   rtx body = XVECEXP (PATTERN (insn), 0, 0);
!   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
! 
!   if (! STACK_TOP_P (operands[0]))
!     abort ();
! 
!   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
! 
!   if (STACK_REG_P (operands[1])
!       && stack_top_dies
!       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
!       && REGNO (operands[1]) != FIRST_STACK_REG)
!     {
!       /* If both the top of the 387 stack dies, and the other operand
! 	 is also a stack register that dies, then this must be a
! 	 `fcompp' float compare */
! 
!       if (unordered_compare)
! 	output_asm_insn ("fucompp", operands);
!       else
! 	output_asm_insn ("fcompp", operands);
!     }
!   else
      {
!       static char buf[100];
! 
!       /* Decide if this is the integer or float compare opcode, or the
! 	 unordered float compare. */
! 
!       if (unordered_compare)
! 	strcpy (buf, "fucom");
!       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
! 	strcpy (buf, "fcom");
!       else
! 	strcpy (buf, "ficom");
! 
!       /* Modify the opcode if the 387 stack is to be popped. */
! 
!       if (stack_top_dies)
! 	strcat (buf, "p");
! 
!       if (NON_STACK_REG_P (operands[1]))
! 	output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
!       else
!         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
!     }
  
!   /* Now retrieve the condition code. */
  
!   return output_fp_cc0_set (insn);
  }
- 
- /* Output opcodes to transfer the results of FP compare or test INSN
-    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
-    result of the compare or test is unordered, no comparison operator
-    succeeds except NE.  Return an output template, if any.  */
  
! char *
! output_fp_cc0_set (insn)
!      rtx insn;
  {
!   rtx xops[3];
!   rtx unordered_label;
!   rtx next;
!   enum rtx_code code;
  
!   xops[0] = gen_rtx (REG, HImode, 0);
!   output_asm_insn (AS1 (fnsts%W0,%0), xops);
  
!   if (! TARGET_IEEE_FP)
!     return "sahf";
  
-   next = next_cc0_user (insn);
-   if (next == NULL_RTX)
-     abort ();
  
!   if (GET_CODE (next) == JUMP_INSN
!       && GET_CODE (PATTERN (next)) == SET
!       && SET_DEST (PATTERN (next)) == pc_rtx
!       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
!     {
!       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
!     }
!   else if (GET_CODE (PATTERN (next)) == SET)
      {
!       code = GET_CODE (SET_SRC (PATTERN (next)));
      }
!   else
!     abort ();
  
!   xops[0] = gen_rtx (REG, QImode, 0);
  
!   switch (code)
      {
!     case GT:
!       xops[1] = GEN_INT (0x45);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       /* je label */
!       break;
  
-     case LT:
-       xops[1] = GEN_INT (0x45);
-       xops[2] = GEN_INT (0x01);
-       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
-       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
-       /* je label */
-       break;
  
!     case GE:
!       xops[1] = GEN_INT (0x05);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       /* je label */
!       break;
  
-     case LE:
-       xops[1] = GEN_INT (0x45);
-       xops[2] = GEN_INT (0x40);
-       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
-       output_asm_insn (AS1 (dec%B0,%h0), xops);
-       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
-       /* jb label */
-       break;
  
-     case EQ:
-       xops[1] = GEN_INT (0x45);
-       xops[2] = GEN_INT (0x40);
-       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
-       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
-       /* je label */
-       break;
  
-     case NE:
-       xops[1] = GEN_INT (0x44);
-       xops[2] = GEN_INT (0x40);
-       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
-       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
-       /* jne label */
-       break;
  
!     case GTU:
!     case LTU:
!     case GEU:
!     case LEU:
!     default:
!       abort ();
      }
!   RET;
  }
- 
- #define MAX_386_STACK_LOCALS 2
  
! static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
  
! /* Define the structure for the machine field in struct function.  */
! struct machine_function
  {
!   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
! };
  
- /* Functions to save and restore i386_stack_locals.
-    These will be called, via pointer variables,
-    from push_function_context and pop_function_context.  */
  
! void
! save_386_machine_status (p)
!      struct function *p;
  {
!   p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
!   bcopy ((char *) i386_stack_locals, (char *) p->machine->i386_stack_locals,
! 	 sizeof i386_stack_locals);
  }
  
! void
! restore_386_machine_status (p)
!      struct function *p;
  {
!   bcopy ((char *) p->machine->i386_stack_locals, (char *) i386_stack_locals,
! 	 sizeof i386_stack_locals);
!   free (p->machine);
  }
  
- /* Clear stack slot assignments remembered from previous functions.
-    This is called from INIT_EXPANDERS once before RTL is emitted for each
-    function.  */
  
! void
! clear_386_stack_locals ()
  {
!   enum machine_mode mode;
!   int n;
  
!   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
!        mode = (enum machine_mode) ((int) mode + 1))
!     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
!       i386_stack_locals[(int) mode][n] = NULL_RTX;
  
!   /* Arrange to save and restore i386_stack_locals around nested functions.  */
!   save_machine_status = save_386_machine_status;
!   restore_machine_status = restore_386_machine_status;
! }
  
! /* Return a MEM corresponding to a stack slot with mode MODE.
!    Allocate a new slot if necessary.
  
!    The RTL for a function can have several slots available: N is
!    which slot to use.  */
  
- rtx
- assign_386_stack_local (mode, n)
-      enum machine_mode mode;
-      int n;
- {
-   if (n < 0 || n >= MAX_386_STACK_LOCALS)
-     abort ();
  
!   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
!     i386_stack_locals[(int) mode][n]
!       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
  
!   return i386_stack_locals[(int) mode][n];
  }
--- 1429,3510 ----
    else
      output_asm_insn ("ret", xops);
  }
  
! /* Print an integer constant expression in assembler syntax.  Addition
!    and subtraction are the only arithmetic that may appear in these
!    expressions.  FILE is the stdio stream to write to, X is the rtx, and
!    CODE is the operand print code from the output string.  */
  
! static void
! output_pic_addr_const (file, x, code)
!      FILE *file;
!      rtx x;
!      int code;
  {
!   char buf[256];
  
!   switch (GET_CODE (x))
      {
!     case PC:
!       if (flag_pic)
! 	putc ('.', file);
!       else
! 	abort ();
!       break;
  
!     case SYMBOL_REF:
!     case LABEL_REF:
!       if (GET_CODE (x) == SYMBOL_REF)
! 	assemble_name (file, XSTR (x, 0));
!       else
  	{
! 	  ASM_GENERATE_INTERNAL_LABEL (buf, "L",
! 				       CODE_LABEL_NUMBER (XEXP (x, 0)));
! 	  assemble_name (asm_out_file, buf);
  	}
  
+       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
+ 	fprintf (file, "@GOTOFF(%%ebx)");
+       else if (code == 'P')
+ 	fprintf (file, "@PLT");
+       else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
+ 	fprintf (file, "@GOT");
        else
! 	fprintf (file, "@GOTOFF");
  
!       break;
  
!     case CODE_LABEL:
!       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
!       assemble_name (asm_out_file, buf);
!       break;
  
!     case CONST_INT:
!       fprintf (file, "%d", INTVAL (x));
!       break;
  
!     case CONST:
!       /* This used to output parentheses around the expression,
! 	 but that does not work on the 386 (either ATT or BSD assembler).  */
!       output_pic_addr_const (file, XEXP (x, 0), code);
!       break;
  
!     case CONST_DOUBLE:
!       if (GET_MODE (x) == VOIDmode)
  	{
! 	  /* We can use %d if the number is <32 bits and positive.  */
! 	  if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
! 	    fprintf (file, "0x%x%08x",
! 		     CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
! 	  else
! 	    fprintf (file, "%d", CONST_DOUBLE_LOW (x));
  	}
!       else
! 	/* We can't handle floating point constants;
! 	   PRINT_OPERAND must handle them.  */
! 	output_operand_lossage ("floating constant misused");
!       break;
  
!     case PLUS:
!       /* Some assemblers need integer constants to appear last (eg masm).  */
!       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
  	{
! 	  output_pic_addr_const (file, XEXP (x, 1), code);
! 	  if (INTVAL (XEXP (x, 0)) >= 0)
! 	    fprintf (file, "+");
! 	  output_pic_addr_const (file, XEXP (x, 0), code);
  	}
!       else
  	{
! 	  output_pic_addr_const (file, XEXP (x, 0), code);
! 	  if (INTVAL (XEXP (x, 1)) >= 0)
! 	    fprintf (file, "+");
! 	  output_pic_addr_const (file, XEXP (x, 1), code);
  	}
!       break;
  
!     case MINUS:
!       output_pic_addr_const (file, XEXP (x, 0), code);
!       fprintf (file, "-");
!       output_pic_addr_const (file, XEXP (x, 1), code);
!       break;
  
!     default:
!       output_operand_lossage ("invalid expression as operand");
      }
+ }
+ 
+ /* Meaning of CODE:
+    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
+    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
+    R -- print the prefix for register names.
+    z -- print the opcode suffix for the size of the current operand.
+    * -- print a star (in certain assembler syntax)
+    w -- print the operand as if it's a "word" (HImode) even if it isn't.
+    c -- don't print special prefixes before constant operands.
+    J -- print the appropriate jump operand.
+ */
  
! void
! print_operand (file, x, code)
!      FILE *file;
!      rtx x;
!      int code;
! {
!   if (code)
      {
!       switch (code)
  	{
! 	case '*':
! 	  if (USE_STAR)
! 	    putc ('*', file);
! 	  return;
  
! 	case 'L':
! 	  PUT_OP_SIZE (code, 'l', file);
! 	  return;
  
! 	case 'W':
! 	  PUT_OP_SIZE (code, 'w', file);
! 	  return;
  
! 	case 'B':
! 	  PUT_OP_SIZE (code, 'b', file);
! 	  return;
  
! 	case 'Q':
! 	  PUT_OP_SIZE (code, 'l', file);
! 	  return;
  
! 	case 'S':
! 	  PUT_OP_SIZE (code, 's', file);
! 	  return;
  
! 	case 'T':
! 	  PUT_OP_SIZE (code, 't', file);
! 	  return;
  
! 	case 'z':
! 	  /* 387 opcodes don't get size suffixes if the operands are
! 	     registers. */
  
! 	  if (STACK_REG_P (x))
! 	    return;
  
! 	  /* this is the size of op from size of operand */
! 	  switch (GET_MODE_SIZE (GET_MODE (x)))
! 	    {
! 	    case 1:
! 	      PUT_OP_SIZE ('B', 'b', file);
! 	      return;
  
! 	    case 2:
! 	      PUT_OP_SIZE ('W', 'w', file);
! 	      return;
  
! 	    case 4:
! 	      if (GET_MODE (x) == SFmode)
! 		{
! 		  PUT_OP_SIZE ('S', 's', file);
! 		  return;
! 		}
! 	      else
! 		PUT_OP_SIZE ('L', 'l', file);
! 	      return;
  
! 	    case 12:
! 		  PUT_OP_SIZE ('T', 't', file);
! 		  return;
  
! 	    case 8:
! 	      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
! 		{
! #ifdef GAS_MNEMONICS
! 		  PUT_OP_SIZE ('Q', 'q', file);
! 		  return;
! #else
! 		  PUT_OP_SIZE ('Q', 'l', file);	/* Fall through */
! #endif
! 		}
  
! 	      PUT_OP_SIZE ('Q', 'l', file);
! 	      return;
! 	    }
  
! 	case 'b':
! 	case 'w':
! 	case 'k':
! 	case 'h':
! 	case 'y':
! 	case 'P':
! 	  break;
  
! 	case 'J':
! 	  switch (GET_CODE (x))
! 	    {
! 	      /* These conditions are appropriate for testing the result
! 		 of an arithmetic operation, not for a compare operation.
! 	         Cases GE, LT assume CC_NO_OVERFLOW true. All cases assume
! 		 CC_Z_IN_NOT_C false and not floating point.  */
! 	    case NE:  fputs ("jne", file); return;
! 	    case EQ:  fputs ("je",  file); return;
! 	    case GE:  fputs ("jns", file); return;
! 	    case LT:  fputs ("js",  file); return;
! 	    case GEU: fputs ("jmp", file); return;
! 	    case GTU: fputs ("jne",  file); return;
! 	    case LEU: fputs ("je", file); return;
! 	    case LTU: fputs ("#branch never",  file); return;
  
! 	    /* no matching branches for GT nor LE */
! 	    }
! 	  abort ();
  
! 	default:
! 	  {
! 	    char str[50];
  
! 	    sprintf (str, "invalid operand code `%c'", code);
! 	    output_operand_lossage (str);
! 	  }
! 	}
!     }
!   if (GET_CODE (x) == REG)
!     {
!       PRINT_REG (x, code, file);
!     }
!   else if (GET_CODE (x) == MEM)
!     {
!       PRINT_PTR (x, file);
!       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
  	{
! 	  if (flag_pic)
! 	    output_pic_addr_const (file, XEXP (x, 0), code);
! 	  else
! 	    output_addr_const (file, XEXP (x, 0));
  	}
!       else
! 	output_address (XEXP (x, 0));
!     }
!   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
!     {
!       REAL_VALUE_TYPE r; long l;
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_TARGET_SINGLE (r, l);
!       PRINT_IMMED_PREFIX (file);
!       fprintf (file, "0x%x", l);
!     }
!  /* These float cases don't actually occur as immediate operands. */
!  else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
!     {
!       REAL_VALUE_TYPE r; char dstr[30];
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
!       fprintf (file, "%s", dstr);
!     }
!   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == XFmode)
!     {
!       REAL_VALUE_TYPE r; char dstr[30];
!       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
!       REAL_VALUE_TO_DECIMAL (r, "%.22e", dstr);
!       fprintf (file, "%s", dstr);
!     }
!   else 
!     {
!       if (code != 'P')
! 	{
! 	  if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
! 	    PRINT_IMMED_PREFIX (file);
! 	  else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
! 		   || GET_CODE (x) == LABEL_REF)
! 	    PRINT_OFFSET_PREFIX (file);
! 	}
!       if (flag_pic)
! 	output_pic_addr_const (file, x, code);
!       else
! 	output_addr_const (file, x);
      }
  }
  
! /* Print a memory operand whose address is ADDR.  */
  
  void
! print_operand_address (file, addr)
!      FILE *file;
!      register rtx addr;
  {
!   register rtx reg1, reg2, breg, ireg;
!   rtx offset;
  
!   switch (GET_CODE (addr))
      {
!     case REG:
!       ADDR_BEG (file);
!       fprintf (file, "%se", RP);
!       fputs (hi_reg_name[REGNO (addr)], file);
!       ADDR_END (file);
!       break;
  
!     case PLUS:
!       reg1 = 0;
!       reg2 = 0;
!       ireg = 0;
!       breg = 0;
!       offset = 0;
!       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
  	{
! 	  offset = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
  	}
!       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
  	{
! 	  offset = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
  	}
!       if (GET_CODE (addr) != PLUS) ;
!       else if (GET_CODE (XEXP (addr, 0)) == MULT)
  	{
! 	  reg1 = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
  	}
!       else if (GET_CODE (XEXP (addr, 1)) == MULT)
! 	{
! 	  reg1 = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
! 	}
!       else if (GET_CODE (XEXP (addr, 0)) == REG)
! 	{
! 	  reg1 = XEXP (addr, 0);
! 	  addr = XEXP (addr, 1);
! 	}
!       else if (GET_CODE (XEXP (addr, 1)) == REG)
! 	{
! 	  reg1 = XEXP (addr, 1);
! 	  addr = XEXP (addr, 0);
! 	}
!       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
! 	{
! 	  if (reg1 == 0) reg1 = addr;
! 	  else reg2 = addr;
! 	  addr = 0;
! 	}
!       if (offset != 0)
! 	{
! 	  if (addr != 0) abort ();
! 	  addr = offset;
! 	}
!       if ((reg1 && GET_CODE (reg1) == MULT)
! 	  || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
! 	{
! 	  breg = reg2;
! 	  ireg = reg1;
! 	}
!       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
  	{
! 	  breg = reg1;
! 	  ireg = reg2;
  	}
  
!       if (ireg != 0 || breg != 0)
  	{
! 	  int scale = 1;
  
! 	  if (addr != 0)
  	    {
! 	      if (GET_CODE (addr) == LABEL_REF)
! 		output_asm_label (addr);
! 	      else
! 		{
! 		  if (flag_pic)
! 		    output_pic_addr_const (file, addr, 0);
! 		  else
! 		    output_addr_const (file, addr);
! 		}
  	    }
  
!   	  if (ireg != 0 && GET_CODE (ireg) == MULT)
  	    {
! 	      scale = INTVAL (XEXP (ireg, 1));
! 	      ireg = XEXP (ireg, 0);
  	    }
  
! 	  /* The stack pointer can only appear as a base register,
! 	     never an index register, so exchange the regs if it is wrong. */
  
! 	  if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
! 	    {
! 	      rtx tmp;
  
! 	      tmp = breg;
! 	      breg = ireg;
! 	      ireg = tmp;
! 	    }
  
! 	  /* output breg+ireg*scale */
! 	  PRINT_B_I_S (breg, ireg, scale, file);
! 	  break;
  	}
  
!     case MULT:
!       {
! 	int scale;
! 	if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
! 	  {
! 	    scale = INTVAL (XEXP (addr, 0));
! 	    ireg = XEXP (addr, 1);
! 	  }
! 	else
! 	  {
! 	    scale = INTVAL (XEXP (addr, 1));
! 	    ireg = XEXP (addr, 0);
! 	  }
! 	output_addr_const (file, const0_rtx);
! 	PRINT_B_I_S ((rtx) 0, ireg, scale, file);
!       }
!       break;
  
!     default:
!       if (GET_CODE (addr) == CONST_INT
! 	  && INTVAL (addr) < 0x8000
! 	  && INTVAL (addr) >= -0x8000)
! 	fprintf (file, "%d", INTVAL (addr));
!       else
  	{
! 	  if (flag_pic)
! 	    output_pic_addr_const (file, addr, 0);
! 	  else
! 	    output_addr_const (file, addr);
  	}
      }
  }
  
! /* Set the cc_status for the results of an insn whose pattern is EXP.
!    On the 80386, we assume that only test and compare insns, as well
!    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
!    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
!    Also, we assume that jumps, moves and sCOND don't affect the condition
!    codes.  All else clobbers the condition codes, by assumption.
  
!    We assume that ALL integer add, minus, etc. instructions effect the
!    condition codes.  This MUST be consistent with i386.md.
  
!    We don't record any float test or compare - the redundant test &
!    compare check in final.c does not handle stack-like regs correctly. */
! 
! void
! notice_update_cc (exp)
!      rtx exp;
! {
!   if (GET_CODE (exp) == SET)
      {
!       /* Jumps do not alter the cc's.  */
!       if (SET_DEST (exp) == pc_rtx)
! 	return;
! #ifdef IS_STACK_MODE
!       /* intel1 
!          Moving into a memory of stack_mode may have been moved
!          in between the use and set of cc0 by loop_spl(). So
!          old value of cc.status must be retained */
!       if(GET_CODE(SET_DEST(exp))==MEM 
!          && IS_STACK_MODE(GET_MODE(SET_DEST(exp))))
!         {
!           return;
!         }
! #endif
!       /* Moving register or memory into a register:
! 	 it doesn't alter the cc's, but it might invalidate
! 	 the RTX's which we remember the cc's came from.
! 	 (Note that moving a constant 0 or 1 MAY set the cc's).  */
!       if (REG_P (SET_DEST (exp))
! 	  && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
! 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
  	{
! 	  if (cc_status.value1
! 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
! 	    cc_status.value1 = 0;
! 	  if (cc_status.value2
! 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
! 	    cc_status.value2 = 0;
! 	  return;
  	}
+       /* Moving register into memory doesn't alter the cc's.
+ 	 It may invalidate the RTX's which we remember the cc's came from.  */
+       if (GET_CODE (SET_DEST (exp)) == MEM
+ 	  && (REG_P (SET_SRC (exp))
+ 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
+ 	{
+ 	  if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
+ 	    cc_status.value1 = 0;
+ 	  if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
+ 	    cc_status.value2 = 0;
+ 	  return;
+ 	}
+       /* Function calls clobber the cc's.  */
+       else if (GET_CODE (SET_SRC (exp)) == CALL)
+ 	{
+ 	  CC_STATUS_INIT;
+ 	  return;
+ 	}
+       /* Tests and compares set the cc's in predictable ways.  */
+       else if (SET_DEST (exp) == cc0_rtx)
+ 	{
+ 	  CC_STATUS_INIT;
+ 	  cc_status.value1 = SET_SRC (exp);
+ 	  return;
+ 	}
+       /* Certain instructions effect the condition codes. */
+       else if (GET_MODE (SET_SRC (exp)) == SImode
+ 	       || GET_MODE (SET_SRC (exp)) == HImode
+ 	       || GET_MODE (SET_SRC (exp)) == QImode)
+ 	switch (GET_CODE (SET_SRC (exp)))
+ 	  {
+ 	  case ASHIFTRT: case LSHIFTRT:
+ 	  case ASHIFT: case LSHIFT:
+ 	    /* Shifts on the 386 don't set the condition codes if the
+ 	       shift count is zero. */
+ 	    if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
+ 	      {
+ 		CC_STATUS_INIT;
+ 		break;
+ 	      }
+ 	    /* We assume that the CONST_INT is non-zero (this rtx would
+ 	       have been deleted if it were zero. */
  
! 	  case PLUS: case MINUS: case NEG:
! 	  case AND: case IOR: case XOR:
! 	    cc_status.flags = CC_NO_OVERFLOW;
! 	    cc_status.value1 = SET_SRC (exp);
! 	    cc_status.value2 = SET_DEST (exp);
! 	    break;
  
! 	  default:
! 	    CC_STATUS_INIT;
! 	  }
!       else
  	{
! 	  CC_STATUS_INIT;
! 	}
!     }
!   else if (GET_CODE (exp) == PARALLEL
! 	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
!     {
!       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
! 	return;
!       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
! 	{
! 	  CC_STATUS_INIT;
! 	  if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
! 	    cc_status.flags |= CC_IN_80387;
  	  else
! 	    cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
! 	  return;
  	}
!       CC_STATUS_INIT;
!     }
!   else
!     {
!       CC_STATUS_INIT;
!     }
! }
! 
! /* Split one or more DImode RTL references into pairs of SImode
!    references.  The RTL can be REG, offsettable MEM, integer constant, or
!    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
!    split and "num" is its length.  lo_half and hi_half are output arrays
!    that parallel "operands". */
  
! void
! split_di (operands, num, lo_half, hi_half)
!      rtx operands[];
!      int num;
!      rtx lo_half[], hi_half[];
! {
!   while (num--)
!     {
!       if (GET_CODE (operands[num]) == REG)
  	{
! 	  lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
! 	  hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
  	}
!       else if (CONSTANT_P (operands[num]))
  	{
! 	  split_double (operands[num], &lo_half[num], &hi_half[num]);
  	}
!       else if (offsettable_memref_p (operands[num]))
! 	{
! 	  lo_half[num] = operands[num];
! 	  hi_half[num] = adj_offsettable_operand (operands[num], 4);
! 	}
!       else
! 	abort();
!     }
! }
! 
! /* Return 1 if this is a valid binary operation on a 387.
!    OP is the expression matched, and MODE is its mode. */
! 
! int
! binary_387_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
! {
!   if (mode != VOIDmode && mode != GET_MODE (op))
!     return 0;
  
+   switch (GET_CODE (op))
+     {
+     case PLUS:
      case MINUS:
!     case MULT:
!     case DIV:
!       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
  
      default:
!       return 0;
      }
  }
  
! /* Return 1 if this is a valid conversion operation on a 387.
!    OP is the expression matched, and MODE is its mode. */
! 
! int
! convert_387_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
  {
!   if (mode != VOIDmode && mode != GET_MODE (op))
!     return 0;
! 
!   switch (GET_CODE (op))
      {
!     case FLOAT:
!       return GET_MODE (XEXP (op, 0)) == SImode;
  
!     case FLOAT_EXTEND:
!       return ((mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode)
! 	      || (mode == XFmode && GET_MODE (XEXP (op, 0)) == DFmode)
! 	      || (mode == XFmode && GET_MODE (XEXP (op, 0)) == SFmode));
  
!     default:
!       return 0;
!     }
! }
  
! /* Return 1 if this is a valid shift or rotate operation on a 386.
!    OP is the expression matched, and MODE is its mode. */
  
! int
! shift_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
! {
!   rtx operand = XEXP (op, 0);
  
!   if (mode != VOIDmode && mode != GET_MODE (op))
!     return 0;
  
!   if (GET_MODE (operand) != GET_MODE (op)
!       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
!     return 0;
  
!   return (GET_CODE (op) == ASHIFT
! 	  || GET_CODE (op) == ASHIFTRT
! 	  || GET_CODE (op) == LSHIFTRT
! 	  || GET_CODE (op) == ROTATE
! 	  || GET_CODE (op) == ROTATERT);
! }
  
! /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
!    MODE is not used.  */
  
! int
! VOIDmode_compare_op (op, mode)
!     register rtx op;
!     enum machine_mode mode;
! {
!   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
! }
! 
! /* Output code to perform a 387 binary operation in INSN, one of PLUS,
!    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
!    is the expression of the binary operation.  The output may either be
!    emitted here, or returned to the caller, like all output_* functions.
  
!    There is no guarantee that the operands are the same mode, as they
!    might be within FLOAT or FLOAT_EXTEND expressions. */
  
! char *
! output_387_binary_op (insn, operands)
!      rtx insn;
!      rtx *operands;
! {
!   rtx temp;
!   char *base_op;
!   static char buf[100];
  
!   switch (GET_CODE (operands[3]))
!     {
!     case PLUS:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fiadd";
!       else
! 	base_op = "fadd";
!       break;
  
!     case MINUS:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fisub";
!       else
! 	base_op = "fsub";
!       break;
  
!     case MULT:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fimul";
!       else
! 	base_op = "fmul";
!       break;
  
!     case DIV:
!       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
! 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
! 	base_op = "fidiv";
!       else
! 	base_op = "fdiv";
!       break;
  
!     default:
!       abort ();
!     }
  
!   strcpy (buf, base_op);
  
!   switch (GET_CODE (operands[3]))
      {
!     case MULT:
!     case PLUS:
!       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  	{
! 	  temp = operands[2];
! 	  operands[2] = operands[1];
! 	  operands[1] = temp;
  	}
  
!       if (GET_CODE (operands[2]) == MEM)
! 	return strcat (buf, AS1 (%z2,%2));
  
!       if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
!       else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
! 
!       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
! 	return strcat (buf, AS2 (p,%2,%0));
! 
!       if (STACK_TOP_P (operands[0]))
! 	return strcat (buf, AS2 (,%y2,%0));
!       else
! 	return strcat (buf, AS2 (,%2,%0));
! 
!     case MINUS:
!     case DIV:
!       if (GET_CODE (operands[1]) == MEM)
! 	return strcat (buf, AS1 (r%z1,%1));
! 
!       if (GET_CODE (operands[2]) == MEM)
! 	return strcat (buf, AS1 (%z2,%2));
! 
!       if (NON_STACK_REG_P (operands[1]))
  	{
! 	  output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
! 	  RET;
  	}
!       else if (NON_STACK_REG_P (operands[2]))
  	{
! 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
! 	  RET;
  	}
! 
!       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
! 	abort ();
! 
!       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
! 	return strcat (buf, AS2 (rp,%2,%0));
! 
!       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
! 	return strcat (buf, AS2 (p,%1,%0));
! 
!       if (STACK_TOP_P (operands[0]))
  	{
! 	  if (STACK_TOP_P (operands[1]))
! 	    return strcat (buf, AS2 (,%y2,%0));
! 	  else
! 	    return strcat (buf, AS2 (r,%y1,%0));
  	}
+       else if (STACK_TOP_P (operands[1]))
+ 	return strcat (buf, AS2 (,%1,%0));
+       else
+ 	return strcat (buf, AS2 (r,%2,%0));
  
!     default:
!       abort ();
!     }
! }
! 
! /* Output code for INSN to convert a float to a signed int.  OPERANDS
!    are the insn operands.  The output may be SFmode or DFmode and the
!    input operand may be SImode or DImode.  As a special case, make sure
!    that the 387 stack top dies if the output mode is DImode, because the
!    hardware requires this.  */
  
! char *
! output_fix_trunc (insn, operands)
!      rtx insn;
!      rtx *operands;
! {
!   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
!   rtx xops[2];
  
!   if (! STACK_TOP_P (operands[1]) ||
!       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
!     abort ();
  
!   xops[0] = GEN_INT (12);
!   xops[1] = operands[4];
  
!   output_asm_insn (AS1 (fnstc%W2,%2), operands);
!   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
!   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
!   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
!   output_asm_insn (AS1 (fldc%W3,%3), operands);
  
!   if (NON_STACK_REG_P (operands[0]))
!     output_to_reg (operands[0], stack_top_dies);
!   else if (GET_CODE (operands[0]) == MEM)
!     {
!       if (stack_top_dies)
! 	output_asm_insn (AS1 (fistp%z0,%0), operands);
!       else
! 	output_asm_insn (AS1 (fist%z0,%0), operands);
!     }
!   else
!     abort ();
  
!   return AS1 (fldc%W2,%2);
! }
! 
! /* Output code for INSN to compare OPERANDS.  The two operands might
!    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
!    expression.  If the compare is in mode CCFPEQmode, use an opcode that
!    will not fault if a qNaN is present. */
  
! char *
! output_float_compare (insn, operands)
!      rtx insn;
!      rtx *operands;
! {
!   int stack_top_dies;
!   rtx body = XVECEXP (PATTERN (insn), 0, 0);
!   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
  
!   /* intel1 */
!   rtx tmp;
!   if (! STACK_TOP_P (operands[0]))
!     {
!       tmp = operands[0];
!       operands[0] = operands[1];
!       operands[1] = tmp;
!       cc_status.flags |= CC_REVERSED;
!     }
!     
!   if (! STACK_TOP_P (operands[0]))
!     abort ();
  
!   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
  
!   if (STACK_REG_P (operands[1])
!       && stack_top_dies
!       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
!       && REGNO (operands[1]) != FIRST_STACK_REG)
!     {
!       /* If both the top of the 387 stack dies, and the other operand
! 	 is also a stack register that dies, then this must be a
! 	 `fcompp' float compare */
! 
!       if (unordered_compare)
! 	output_asm_insn ("fucompp", operands);
        else
! 	output_asm_insn ("fcompp", operands);
      }
+   else
+     {
+       static char buf[100];
+ 
+       /* Decide if this is the integer or float compare opcode, or the
+ 	 unordered float compare. */
+ 
+       if (unordered_compare)
+ 	strcpy (buf, "fucom");
+       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
+ 	strcpy (buf, "fcom");
+       else
+ 	strcpy (buf, "ficom");
+ 
+       /* Modify the opcode if the 387 stack is to be popped. */
+ 
+       if (stack_top_dies)
+ 	strcat (buf, "p");
+ 
+       if (NON_STACK_REG_P (operands[1]))
+ 	output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
+       else
+         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
+     }
+ 
+   /* Now retrieve the condition code. */
+ 
+   return output_fp_cc0_set (insn);
  }
  
! /* Output opcodes to transfer the results of FP compare or test INSN
!    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
!    result of the compare or test is unordered, no comparison operator
!    succeeds except NE.  Return an output template, if any.  */
  
! char *
! output_fp_cc0_set (insn)
!      rtx insn;
! {
!   rtx xops[3];
!   rtx unordered_label;
!   rtx next;
!   enum rtx_code code;
  
!   xops[0] = gen_rtx (REG, HImode, 0);
!   output_asm_insn (AS1 (fnsts%W0,%0), xops);
  
! 
!   if (! TARGET_IEEE_FP)
      {
!       /* intel1 */
!       if (!(cc_status.flags & CC_REVERSED))
!         {
!           next = next_cc0_user (insn);
!         
!           if (GET_CODE (next) == JUMP_INSN
!               && GET_CODE (PATTERN (next)) == SET
!               && SET_DEST (PATTERN (next)) == pc_rtx
!               && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
!             {
!               code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
!             }
!           else if (GET_CODE (PATTERN (next)) == SET)
!             {
!               code = GET_CODE (SET_SRC (PATTERN (next)));
!             }
!           else
!             {
!               return "sahf";
!             }
!           if (code == GT || code == LT || code == EQ || code == NE
!               || code == LE || code == GE)
!             { /* We will test eax directly */
!               cc_status.flags |= CC_TEST_AX;
!               RET;
!             }
!         }
!       return "sahf";
!     }
  
!   next = next_cc0_user (insn);
!   if (next == NULL_RTX)
!     abort ();
  
!   if (GET_CODE (next) == JUMP_INSN
!       && GET_CODE (PATTERN (next)) == SET
!       && SET_DEST (PATTERN (next)) == pc_rtx
!       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
!     {
!       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
      }
!   else if (GET_CODE (PATTERN (next)) == SET)
      {
!       code = GET_CODE (SET_SRC (PATTERN (next)));
      }
    else
+     abort ();
+ 
+   xops[0] = gen_rtx (REG, QImode, 0);
+ 
+   switch (code)
      {
!     case GT:
!       xops[1] = GEN_INT (0x45);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       /* je label */
!       break;
! 
!     case LT:
!       xops[1] = GEN_INT (0x45);
!       xops[2] = GEN_INT (0x01);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
!       /* je label */
!       break;
! 
!     case GE:
!       xops[1] = GEN_INT (0x05);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       /* je label */
!       break;
! 
!     case LE:
!       xops[1] = GEN_INT (0x45);
!       xops[2] = GEN_INT (0x40);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       output_asm_insn (AS1 (dec%B0,%h0), xops);
!       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
!       /* jb label */
!       break;
! 
!     case EQ:
!       xops[1] = GEN_INT (0x45);
!       xops[2] = GEN_INT (0x40);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
!       /* je label */
!       break;
! 
!     case NE:
!       xops[1] = GEN_INT (0x44);
!       xops[2] = GEN_INT (0x40);
!       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
!       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
!       /* jne label */
!       break;
! 
!     case GTU:
!     case LTU:
!     case GEU:
!     case LEU:
!     default:
!       abort ();
      }
+   RET;
+ }
+ 
+ #define MAX_386_STACK_LOCALS 2
+ 
+ static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
+ 
+ /* Define the structure for the machine field in struct function.  */
+ struct machine_function
+ {
+   rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
+ };
+ 
+ /* Functions to save and restore i386_stack_locals.
+    These will be called, via pointer variables,
+    from push_function_context and pop_function_context.  */
+ 
+ void
+ save_386_machine_status (p)
+      struct function *p;
+ {
+   p->machine = (struct machine_function *) xmalloc (sizeof i386_stack_locals);
+   bcopy (i386_stack_locals, p->machine->i386_stack_locals,
+ 	 sizeof i386_stack_locals);
  }
  
  void
! restore_386_machine_status (p)
!      struct function *p;
  {
!   bcopy (p->machine->i386_stack_locals, i386_stack_locals,
! 	 sizeof i386_stack_locals);
!   free (p->machine);
  }
  
! /* Clear stack slot assignments remembered from previous functions.
!    This is called from INIT_EXPANDERS once before RTL is emitted for each
!    function.  */
! 
! void
! clear_386_stack_locals ()
  {
!   enum machine_mode mode;
!   int n;
  
!   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
!        mode = (enum machine_mode) ((int) mode + 1))
!     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
!       i386_stack_locals[(int) mode][n] = NULL_RTX;
  
!   /* Arrange to save and restore i386_stack_locals around nested functions.  */
!   save_machine_status = save_386_machine_status;
!   restore_machine_status = restore_386_machine_status;
  }
  
! /* Return a MEM corresponding to a stack slot with mode MODE.
!    Allocate a new slot if necessary.
  
!    The RTL for a function can have several slots available: N is
!    which slot to use.  */
! 
! rtx
! assign_386_stack_local (mode, n)
!      enum machine_mode mode;
!      int n;
  {
!   if (n < 0 || n >= MAX_386_STACK_LOCALS)
!     abort ();
  
!   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
!   {
!     i386_stack_locals[(int) mode][n]
!       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
!   }
!   return i386_stack_locals[(int) mode][n];
! }
  
  
! /* all functions after here added by intel1 */
! /* intel1 */
! int is_mul(op,mode)
!     register rtx op;
!     enum machine_mode mode;
! {
!   return(GET_CODE(op)==MULT);
  }
  
! /* intel1 */
! int is_div(op,mode)
      register rtx op;
      enum machine_mode mode;
  {
!   return(GET_CODE(op)==DIV);
  }
  
! /* Create a new copy of an rtx.
!    Recursively copies the operands of the rtx,
!    except for those few rtx codes that are sharable.
!    Doesn't share CONST  */
  
! rtx
! copy_all_rtx (orig)
!      register rtx orig;
  {
!   register rtx copy;
!   register int i, j;
!   register RTX_CODE code;
!   register char *format_ptr;
  
!   code = GET_CODE (orig);
! 
!   switch (code)
      {
!     case REG:
!     case QUEUED:
!     case CONST_INT:
!     case CONST_DOUBLE:
!     case SYMBOL_REF:
!     case CODE_LABEL:
!     case PC:
!     case CC0:
!     case SCRATCH:
!       /* SCRATCH must be shared because they represent distinct values. */
!       return orig;
  
! #if 0
!     case CONST:
!       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
! 	 a LABEL_REF, it isn't sharable.  */
!       if (GET_CODE (XEXP (orig, 0)) == PLUS
! 	  && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
! 	  && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
! 	return orig;
        break;
+ #endif
+       /* A MEM with a constant address is not sharable.  The problem is that
+ 	 the constant address may need to be reloaded.  If the mem is shared,
+ 	 then reloading one copy of this mem will cause all copies to appear
+ 	 to have been reloaded.  */
+     }
+ 
+   copy = rtx_alloc (code);
+   PUT_MODE (copy, GET_MODE (orig));
+   copy->in_struct = orig->in_struct;
+   copy->volatil = orig->volatil;
+   copy->unchanging = orig->unchanging;
+   copy->integrated = orig->integrated;
+   /* intel1 */
+   copy->is_spill_rtx = orig->is_spill_rtx;
+   
+   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
+ 
+   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
+     {
+       switch (*format_ptr++)
+ 	{
+ 	case 'e':
+ 	  XEXP (copy, i) = XEXP (orig, i);
+ 	  if (XEXP (orig, i) != NULL)
+ 	    XEXP (copy, i) = copy_rtx (XEXP (orig, i));
+ 	  break;
  
! 	case '0':
! 	case 'u':
! 	  XEXP (copy, i) = XEXP (orig, i);
! 	  break;
  
! 	case 'E':
! 	case 'V':
! 	  XVEC (copy, i) = XVEC (orig, i);
! 	  if (XVEC (orig, i) != NULL)
! 	    {
! 	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
! 	      for (j = 0; j < XVECLEN (copy, i); j++)
! 		XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
! 	    }
! 	  break;
  
! 	case 'w':
! 	  XWINT (copy, i) = XWINT (orig, i);
! 	  break;
! 
! 	case 'i':
! 	  XINT (copy, i) = XINT (orig, i);
! 	  break;
! 
! 	case 's':
! 	case 'S':
! 	  XSTR (copy, i) = XSTR (orig, i);
! 	  break;
! 
! 	default:
! 	  abort ();
! 	}
!     }
!   return copy;
! }
! 
! 
! /* try to rewrite a memory address to make it valid */
! void 
! rewrite_address (mem_rtx)
!      rtx mem_rtx;
! {
!   rtx index_rtx, base_rtx, offset_rtx, scale_rtx, ret_rtx;
!   int scale = 1;
!   int offset_adjust = 0;
!   int was_only_offset = 0;
!   rtx mem_addr = XEXP (mem_rtx, 0);
!   char *storage = (char *) oballoc (0);
!   int in_struct = 0;
!   int is_spill_rtx = 0;
! 
!   in_struct = MEM_IN_STRUCT_P (mem_rtx);
!   is_spill_rtx = RTX_IS_SPILL_P (mem_rtx);
! 
!   if (GET_CODE (mem_addr) == PLUS &&
!       GET_CODE (XEXP (mem_addr, 1)) == PLUS &&
!       GET_CODE (XEXP (XEXP (mem_addr, 1), 0)) == REG)
!     {				/* this part is utilized by the combiner */
!       ret_rtx =
! 	gen_rtx (PLUS, GET_MODE (mem_addr),
! 		 gen_rtx (PLUS, GET_MODE (XEXP (mem_addr, 1)),
! 			  XEXP (mem_addr, 0),
! 			  XEXP (XEXP (mem_addr, 1), 0)),
! 		 XEXP (XEXP (mem_addr, 1), 1));
!       if (memory_address_p (GET_MODE (mem_rtx), ret_rtx))
! 	{
! 	  XEXP (mem_rtx, 0) = ret_rtx;
! 	  RTX_IS_SPILL_P (ret_rtx) = is_spill_rtx;
! 	  return;
! 	}
!       obfree (storage);
!     }
! 
!   /* this part is utilized by loop.c */
!   /* If the address contains PLUS (reg,const) and this pattern is invalid
!      in this case - try to rewrite the address to make it valid  intel1
!   */
!   storage = (char *) oballoc (0);
!   index_rtx = base_rtx = offset_rtx = NULL;
!   /* find the base index and offset elements of the memory address */
!   if (GET_CODE (mem_addr) == PLUS)
!     {
!       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
! 	{
! 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
! 	    {
! 	      base_rtx = XEXP (mem_addr, 1);
! 	      index_rtx = XEXP (mem_addr, 0);
! 	    }
! 	  else
! 	    {
! 	      base_rtx = XEXP (mem_addr, 0);
! 	      offset_rtx = XEXP (mem_addr, 1);
! 	    }
! 	}
!       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
! 	{
! 	  index_rtx = XEXP (mem_addr, 0);
! 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
! 	    {
! 	      base_rtx = XEXP (mem_addr, 1);
! 	    }
! 	  else
! 	    {
! 	      offset_rtx = XEXP (mem_addr, 1);
! 	    }
! 	}
!       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
! 	{
! 	  /* intel1 */
! 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == PLUS &&
! 	      GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == MULT &&
! 	      GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 0)) == REG &&
! 	      GET_CODE (XEXP (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0), 1)) == CONST_INT &&
! 	      GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT &&
! 	      GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG &&
! 	      GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF)
! 	    {
! 	      index_rtx = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
! 	      offset_rtx = XEXP (mem_addr, 1);
! 	      base_rtx = XEXP (XEXP (mem_addr, 0), 1);
! 	      offset_adjust = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
! 	    }
! 	  else
! 	    {
! 	      offset_rtx = XEXP (mem_addr, 1);
! 	      index_rtx = XEXP (XEXP (mem_addr, 0), 0);
! 	      base_rtx = XEXP (XEXP (mem_addr, 0), 1);
! 	    }
! 	}
!       else if (GET_CODE (XEXP (mem_addr, 0)) == CONST_INT)
! 	{
! 	  was_only_offset = 1;
! 	  index_rtx = NULL;
! 	  base_rtx = NULL;
! 	  offset_rtx = XEXP (mem_addr, 1);
! 	  offset_adjust = INTVAL (XEXP (mem_addr, 0));
! 	  if (offset_adjust == 0)
! 	    {
! 	      XEXP (mem_rtx, 0) = offset_rtx;
! 	      RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
! 	      return;
! 	    }
! 	}
!       else
! 	{
! 	  obfree (storage);
! 	  return;
! 	}
!     }
!   else if (GET_CODE (mem_addr) == MULT)
!     {
!       index_rtx = mem_addr;
!     }
!   else
!     {
!       obfree (storage);
!       return;
!     }
!   if (index_rtx && GET_CODE (index_rtx) == MULT)
!     {
!       if (GET_CODE (XEXP (index_rtx, 1)) != CONST_INT)
! 	{
! 	  obfree (storage);
! 	  return;
! 	}
!       scale_rtx = XEXP (index_rtx, 1);
!       scale = INTVAL (scale_rtx);
!       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
!     }
!   /* now find which of the elements are invalid and try to fix them */
!   if (index_rtx && GET_CODE (index_rtx) == CONST_INT && base_rtx == NULL)
!     {
!       offset_adjust = INTVAL (index_rtx) * scale;
!       if (offset_rtx && GET_CODE (offset_rtx) == CONST &&
! 	  GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
! 	{
! 	  if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
! 	      GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
! 	    {
! 	      offset_rtx = copy_all_rtx (offset_rtx);
! 	      XEXP (XEXP (offset_rtx, 0), 1) =
! 		gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
! 	      if (!CONSTANT_P (offset_rtx))
! 		{
! 		  obfree (storage);
! 		  return;
! 		}
! 	    }
! 	}
!       else if (offset_rtx && GET_CODE (offset_rtx) == SYMBOL_REF)
! 	{
! 	  offset_rtx =
! 	    gen_rtx (CONST, GET_MODE (offset_rtx),
! 		     gen_rtx (PLUS, GET_MODE (offset_rtx),
! 			      offset_rtx,
! 			      gen_rtx (CONST_INT, 0, offset_adjust)));
! 	  if (!CONSTANT_P (offset_rtx))
! 	    {
! 	      obfree (storage);
! 	      return;
! 	    }
! 	}
!       else if (offset_rtx && GET_CODE (offset_rtx) == CONST_INT)
! 	{
! 	  offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
! 	}
!       else if (!offset_rtx)
! 	{
! 	  offset_rtx = gen_rtx (CONST_INT, 0, 0);
! 	}
!       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
!       XEXP (mem_rtx, 0) = offset_rtx;
!       return;
      }
!   if (base_rtx && GET_CODE (base_rtx) == PLUS &&
!       GET_CODE (XEXP (base_rtx, 0)) == REG &&
!       GET_CODE (XEXP (base_rtx, 1)) == CONST_INT)
      {
!       offset_adjust += INTVAL (XEXP (base_rtx, 1));
!       base_rtx = copy_all_rtx (XEXP (base_rtx, 0));
!     }
!   else if (base_rtx && GET_CODE (base_rtx) == CONST_INT)
!     {
!       offset_adjust += INTVAL (base_rtx);
!       base_rtx = NULL;
!     }
!   if (index_rtx && GET_CODE (index_rtx) == PLUS &&
!       GET_CODE (XEXP (index_rtx, 0)) == REG &&
!       GET_CODE (XEXP (index_rtx, 1)) == CONST_INT)
!     {
!       offset_adjust += INTVAL (XEXP (index_rtx, 1)) * scale;
!       index_rtx = copy_all_rtx (XEXP (index_rtx, 0));
!     }
!   if (index_rtx)
!     {
!       if (!LEGITIMATE_INDEX_P (index_rtx)
!       && !(index_rtx == stack_pointer_rtx && scale == 1 && base_rtx == NULL))
  	{
! 	  obfree (storage);
! 	  return;
  	}
!     }
!   if (base_rtx)
!     {
!       if (!LEGITIMATE_INDEX_P (base_rtx) && GET_CODE (base_rtx) != REG)
  	{
! 	  obfree (storage);
! 	  return;
  	}
!     }
!   if (offset_adjust != 0)
!     {
!       if (offset_rtx)
  	{
! 	  if (GET_CODE (offset_rtx) == CONST &&
! 	      GET_CODE (XEXP (offset_rtx, 0)) == PLUS)
! 	    {
! 	      if (GET_CODE (XEXP (XEXP (offset_rtx, 0), 0)) == SYMBOL_REF &&
! 		  GET_CODE (XEXP (XEXP (offset_rtx, 0), 1)) == CONST_INT)
! 		{
! 		  offset_rtx = copy_all_rtx (offset_rtx);
! 		  XEXP (XEXP (offset_rtx, 0), 1) =
! 		    gen_rtx (CONST_INT, 0, INTVAL (XEXP (XEXP (offset_rtx, 0), 1)) + offset_adjust);
! 		  if (!CONSTANT_P (offset_rtx))
! 		    {
! 		      obfree (storage);
! 		      return;
! 		    }
! 		}
! 	    }
! 	  else if (GET_CODE (offset_rtx) == SYMBOL_REF)
! 	    {
! 	      offset_rtx =
! 		gen_rtx (CONST, GET_MODE (offset_rtx),
! 			 gen_rtx (PLUS, GET_MODE (offset_rtx),
! 				  offset_rtx,
! 				  gen_rtx (CONST_INT, 0, offset_adjust)));
! 	      if (!CONSTANT_P (offset_rtx))
! 		{
! 		  obfree (storage);
! 		  return;
! 		}
! 	    }
! 	  else if (GET_CODE (offset_rtx) == CONST_INT)
! 	    {
! 	      offset_rtx = gen_rtx (CONST_INT, 0, INTVAL (offset_rtx) + offset_adjust);
! 	    }
! 	  else
! 	    {
! 	      obfree (storage);
! 	      return;
! 	    }
  	}
        else
  	{
! 	  offset_rtx = gen_rtx (CONST_INT, 0, offset_adjust);
  	}
!       if (index_rtx)
  	{
! 	  if (base_rtx)
! 	    {
! 	      if (scale != 1)
! 		{
! 		  if (GET_CODE (offset_rtx) == CONST_INT &&
! 		      INTVAL (offset_rtx) == 0)
! 		    {
! 		      ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx),
! 			     gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
! 				      scale_rtx),
! 					 base_rtx);
! 		    }
! 		  else
! 		    {
! 		      ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
! 					 gen_rtx (PLUS, GET_MODE (base_rtx),
! 			     gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
! 				      scale_rtx),
! 						  base_rtx),
! 					 offset_rtx);
! 		    }
! 		}
! 	      else
! 		{
! 		  if (GET_CODE (offset_rtx) == CONST_INT &&
! 		      INTVAL (offset_rtx) == 0)
! 		    {
! 		      ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, base_rtx);
! 		    }
! 		  else
! 		    {
! 		      ret_rtx = gen_rtx (PLUS, GET_MODE (offset_rtx),
! 			     gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx,
! 				      base_rtx),
! 					 offset_rtx);
! 		    }
! 		}
! 	    }
! 	  else
! 	    {
! 	      if (scale != 1)
! 		{
! 		  if (GET_CODE (offset_rtx) == CONST_INT &&
! 		      INTVAL (offset_rtx) == 0)
! 		    {
! 		      ret_rtx = gen_rtx (MULT, GET_MODE (index_rtx), index_rtx, scale_rtx);
! 		    }
! 		  else
! 		    {
! 		      ret_rtx =
! 			gen_rtx (PLUS, GET_MODE (offset_rtx),
! 			     gen_rtx (MULT, GET_MODE (index_rtx), index_rtx,
! 				      scale_rtx),
! 				 offset_rtx);
! 		    }
! 		}
! 	      else
! 		{
! 		  if (GET_CODE (offset_rtx) == CONST_INT &&
! 		      INTVAL (offset_rtx) == 0)
! 		    {
! 		      ret_rtx = index_rtx;
! 		    }
! 		  else
! 		    {
! 		      ret_rtx = gen_rtx (PLUS, GET_MODE (index_rtx), index_rtx, offset_rtx);
! 		    }
! 		}
! 	    }
  	}
!       else
  	{
! 	  if (base_rtx)
! 	    {
! 	      if (GET_CODE (offset_rtx) == CONST_INT &&
! 		  INTVAL (offset_rtx) == 0)
! 		{
! 		  ret_rtx = base_rtx;
! 		}
! 	      else
! 		{
! 		  ret_rtx = gen_rtx (PLUS, GET_MODE (base_rtx), base_rtx, offset_rtx);
! 		}
! 	    }
! 	  else if (was_only_offset)
! 	    {
! 	      ret_rtx = offset_rtx;
! 	    }
  	  else
! 	    {
! 	      obfree (storage);
! 	      return;
! 	    }
  	}
!       XEXP (mem_rtx, 0) = ret_rtx;
!       RTX_IS_SPILL_P (XEXP (mem_rtx, 0)) = is_spill_rtx;
!       return;
!     }
!   else
!     {
!       obfree (storage);
!       return;
      }
  }
  
! /* return 1 if the first insn to set cc before insn also sets the register
!    reg_rtx - otherwise return 0
! */
! int
! last_to_set_cc (reg_rtx, insn)
!      rtx reg_rtx, insn;
  {
!   rtx prev_insn = PREV_INSN (insn);
  
!   while (prev_insn)
      {
!       if (GET_CODE (prev_insn) == NOTE)
! 	{
! 	  ;
! 	}
!       else if (GET_CODE (prev_insn) == INSN)
! 	{
! 	  if (GET_CODE (PATTERN (prev_insn)) != SET)
! 	    {
! 	      return (0);
! 	    }
! 	  if (rtx_equal_p (SET_DEST (PATTERN (prev_insn)), reg_rtx))
! 	    {
! 	      if (sets_condition_code (SET_SRC (PATTERN (prev_insn))))
! 		{
! 		  return (1);
! 		}
! 	      else
! 		{
! 		  return (0);
! 		}
! 	    }
! 	  else if (!doesnt_set_condition_code (SET_SRC (PATTERN (prev_insn))))
! 	    {
! 	      return (0);
! 	    }
! 	}
        else
! 	{
! 	  return (0);
! 	}
!       prev_insn = PREV_INSN (prev_insn);
      }
!   return (0);
  }
  
! int
! doesnt_set_condition_code (pat)
!      rtx pat;
  {
!   switch (GET_CODE (pat))
      {
!     case MEM:
!     case REG:
!       return (1);
  
!     default:
!       return (0);
  
!     }
  }
  
! int
! sets_condition_code (pat)
!      rtx pat;
  {
!   switch (GET_CODE (pat))
!     {
!     case PLUS:
!     case MINUS:
!     case AND:
!     case IOR:
!     case XOR:
!     case NOT:
!     case NEG:
!     case MULT:
!     case DIV:
!     case MOD:
!     case UDIV:
!     case UMOD:
!       return (1);
  
!     default:
!       return (0);
  
!     }
! }
  
  
! /* intel1 */
! int
! str_immediate_operand (op, mode)
!      register rtx op;
!      enum machine_mode mode;
! {
!   if (GET_CODE (op) == CONST_INT && INTVAL (op) <= 32 && INTVAL (op) >= 0)
      {
!       return (1);
      }
!   return (0);
! }
  
! /* intel1 */
! void
! override_options ()
! {
!   register int i, start;
!   register int regno;
!   register enum machine_mode mode;
!   char *p;
! #if 0
!   int blend = 0;
! #endif
  
!   /* only one `-mcpu' allowed */
!   if (TARGET_X && (TARGET_X != TARGET_386) && (TARGET_X != TARGET_486) && (TARGET_X != TARGET_PENTIUM))
!     fatal ("multilple `-mcpu' definitions .\n");
! 
!  /* if `-mcpu' use it, otherwise take default */
!  target_flags |= USE_CPU;
! 
!   if (TARGET_PENTIUM)
!     x86_cpu = PROCESSOR_PENTIUM;
!   else if (TARGET_486)
!     x86_cpu = PROCESSOR_486;
!   else if (TARGET_386)
!     x86_cpu = PROCESSOR_386;
!   else /* no processor type ? */
!     fatal ("no processor type.\n");
!   
! #if 0 /* what happens if we have few -mcpu's, I don't think it's needed */
!   /* Identify the processor type */
!   if (!(TARGET_PENTIUM) && !(TARGET_486) && !(TARGET_386))
!     {
!       x86_cpu = PROCESSOR_PENTIUM;
!       target_flags |= (TARGET_486_SWITCH);
!       blend = 1;
!     }
! 
!   else
      {
!       x86_cpu = PROCESSOR_DEFAULT;
!       if (TARGET_PENTIUM)
! 	{
! 	  x86_cpu = PROCESSOR_PENTIUM;
! 	}
!       if (TARGET_486)
! 	{
! 	  if (x86_cpu != PROCESSOR_DEFAULT)
! 	    {
! 	      error ("conflicting -mX86 : using blend");
! 	      blend = 1;
! 	      x86_cpu = PROCESSOR_PENTIUM;
! 	      target_flags &= ~(TARGET_386_SWITCH);
! 	      target_flags &= ~(TARGET_PENTIUM_SWITCH);
! 	    }
! 	  else
! 	    {
! 	      x86_cpu = PROCESSOR_486;
! 	    }
! 	}
!       if (TARGET_386)
! 	{
! 	  if (x86_cpu != PROCESSOR_DEFAULT)
! 	    {
! 	      error ("conflicting -mX86 : using blend");
! 	      blend = 1;
! 	      x86_cpu = PROCESSOR_486;
! 	      target_flags &= ~(TARGET_386_SWITCH);
! 	      target_flags &= ~(TARGET_PENTIUM_SWITCH);
! 	      target_flags |= (TARGET_486_SWITCH);
! 	    }
! 	  else
! 	    {
! 	      x86_cpu = PROCESSOR_386;
! 	    }
! 	}
  
  
!     }
! #endif
!   if (opt_level >= 4)
!     {
!       if (TARGET_486)
!         {
! 	  if (opt_level == 4
! 	      && !flag_no_interleave_stack_non_stack)
! 	    {
! 	      flag_interleave_stack_non_stack = 1;
! 	      flag_schedule_insns = 1;
! 	    }
!         }
! #if 0
!       if(TARGET_BLEND)
!         {
!           if (!flag_no_risc)
!             flag_risc = 1;
!           if (!flag_no_risc_const)
!             flag_risc_const = 1;
!           if (!flag_no_recombine)
!             flag_recombine = 1;
!         }
! #endif
!       if (TARGET_PENTIUM)
!         {
!           if (!flag_no_risc)
!             flag_risc = 1;
!           if (!flag_no_risc_const)
!             flag_risc_const = 1;
!           /*if (!flag_no_recombine)
!             flag_recombine = 1;*/
! 	  if (opt_level == 4
! 	      && !flag_no_schedule_stack_reg_insns)
! 	    {
! 	      flag_schedule_stack_reg_insns = 1;
! 	      flag_schedule_insns = 1;
! 	    }
! 	  if (opt_level == 4
! 	      && !flag_no_interleave_stack_non_stack)
! 	    {
! 	      flag_interleave_stack_non_stack = 1;
! 	      flag_schedule_insns = 1;
! 	    }
!         }
!     }
! }
  
  
  
  
! optimization_options (level)
!      int level;
! {
!   opt_level = level;
!   if (level > 0)
!     {
!       flag_opt_reg_use = 1;
!       flag_reduce_index_givs = 1;
      }
!   if (level >= 2)
!     {
! #ifdef INSN_SCHEDULING
!       flag_schedule_insns = 0;
!       flag_schedule_insns_after_reload = 0;
! #endif
!     }
!   if (level >= 3)
!     {
!       flag_inline_functions = 1;
!       flag_jump_back = 1;
!       flag_copy_prop = 1;
!       flag_compare_elim = 1;
!       flag_sftwr_pipe = 1;
!       flag_omit_frame_pointer = 1;
! 	  /*flag_reg_reg_copy_opt = 1; */
!       flag_opt_reg_stack = 1;
! 	  /*flag_loop_after_global = 1; */
!       flag_peep_spills = 1;
!       flag_replace_stack_mem = 1;
!       flag_opt_jumps_out = 1;
!       flag_replace_mem = 1;
!       flag_correct_cse_mistakes = 1;
!       flag_push_load_into_loop = 1;
!       flag_replace_reload_regs = 1;
!       flag_sign_extension_elim = 1;
!       flag_lift_stores = 1;
!       flag_runtime_lift_stores = 1;
!     }
!   if (level >= 4)
!     {
! #ifdef INSN_SCHEDULING
!       flag_schedule_insns_after_reload = 1;
!       flag_swap_for_agi = 1;
!       if (TARGET_PENTIUM)
! 	{
! 		  /*flag_risc = 1; */
! 	  flag_risc_const = 1;
! 	  /*flag_recombine = 1;*/
! 	  if (level == 4)
! 	    {
! 	      flag_schedule_stack_reg_insns = 1;
! 	      flag_schedule_insns = 1;
! 	    }
! 	}
! #endif
!     }
!   if (level >= 5)
!     {
! #ifdef INSN_SCHEDULING
!       flag_schedule_insns = 1;
! #endif
!     }
!   if (flag_no_risc)
!     flag_risc = 0;
!   if (flag_no_risc_const)
!     flag_risc_const = 0;
!   if (flag_no_recombine)
!     flag_recombine = 0;
!   if (flag_no_risc_mem_dest)
!     flag_risc_mem_dest = 0;
  }
  
! /* intel1 */
  
! int
! is_fp_insn (insn)
!      rtx insn;
  {
!   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
!       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
! 	  || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode))
!     {
!       return (1);
!     }
!   return (0);
! }
  
  
! /*
!   Return 1 if the mode of the SET_DEST of insn is floating point
!   and it is not an fld or a move from memory to memory.
!   Otherwise return 0
! */
! int
! is_fp_dest (insn)
!      rtx insn;
  {
!   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
!       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
! 	  || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
!       && GET_CODE (SET_DEST (PATTERN (insn))) == REG
!       && REGNO (SET_DEST (PATTERN (insn))) >= FIRST_FLOAT_REG
!       && GET_CODE (SET_SRC (insn)) != MEM
!      )
!     {
!       return (1);
!     }
!   return (0);
  }
  
! /*
!   Return 1 if the mode of the SET_DEST floating point and is memory
!   and the source is a register.  
! */
! int
! is_fp_store (insn)
!      rtx insn;
  {
!   if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
!       && (GET_MODE (SET_DEST (PATTERN (insn))) == DFmode
! 	  || GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
!       && GET_CODE (SET_DEST (PATTERN (insn))) == MEM
!       && GET_CODE (SET_SRC (PATTERN (insn))) == REG
!      )
!     {
!       return (1);
!     }
!   return (0);
  }
  
  
! /*
!   Return 1 if dep_insn sets a register which insn uses as a base
!   or index to reference memory.
!   otherwise return 0
! */
! int
! agi_dependent (insn, dep_insn)
!      rtx insn, dep_insn;
  {
!   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
!       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG)
!     {
!       return (reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn));
!     }
!   if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET
!       && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM
!       && push_operand (SET_DEST (PATTERN (dep_insn)),
!                        GET_MODE (SET_DEST (PATTERN (dep_insn))))
!      )
!     {
!       return (reg_mentioned_in_mem (stack_pointer_rtx, insn));
!     }
!   
!   return (0);
! }
  
! /*
!   Return 1 if reg is used in rtl as a base or index for a memory ref
!   otherwise return 0.
! */
! int
! reg_mentioned_in_mem (reg, rtl)
!      rtx reg, rtl;
! {
!   register char *fmt;
!   register int i;
!   register enum rtx_code code;
  
!   if (rtl == NULL)
!     return (0);
  
!   code = GET_CODE (rtl);
  
!   switch (code)
!     {
!     case HIGH:
!     case CONST_INT:
!     case CONST:
!     case CONST_DOUBLE:
!     case SYMBOL_REF:
!     case LABEL_REF:
!     case PC:
!     case CC0:
!     case SUBREG:
!       return (0);
  
  
!     }
  
!   if (code == MEM && reg_mentioned_p (reg, rtl))
!     {
!       return (1);
!     }
! 
!   fmt = GET_RTX_FORMAT (code);
! 
!   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
!     {
!       if (fmt[i] == 'E')
! 	{
! 	  register int j;
! 	  for (j = XVECLEN (rtl, i) - 1; j >= 0; j--)
! 	    if (reg_mentioned_in_mem (reg, XVECEXP (rtl, i, j)))
! 	      return 1;
! 	}
!       else if (fmt[i] == 'e'
! 	       && reg_mentioned_in_mem (reg, XEXP (rtl, i)))
! 	return 1;
!     }
!   return (0);
  }
+ 
diff -rNci gcc-2.7.2/config/i386/i386.h gcc-2.7.2p/config/i386/i386.h
*** gcc-2.7.2/config/i386/i386.h	Fri Sep 22 22:42:57 1995
--- gcc-2.7.2p/config/i386/i386.h	Tue Jan 23 10:31:11 1996
***************
*** 2,7 ****
--- 2,10 ----
     (386, 486, Pentium).
     Copyright (C) 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
  
+    Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
+    (tevi@iil.intel.com).
+ 
  This file is part of GNU CC.
  
  GNU CC is free software; you can redistribute it and/or modify
***************
*** 56,179 ****
  /* Run-time compilation parameters selecting different hardware subsets.  */
  
  extern int target_flags;
  
  /* Macros used in the machine description to test the flags.  */
  
  /* configure can arrange to make this 2, to force a 486.  */
  #ifndef TARGET_CPU_DEFAULT
! #define TARGET_CPU_DEFAULT 0
  #endif
  
! /* Masks for the -m switches */
! #define MASK_80387		000000000001	/* Hardware floating point */
! #define MASK_486		000000000002	/* 80486 specific */
! #define MASK_NOTUSED1		000000000004	/* bit not currently used */
! #define MASK_RTD		000000000010	/* Use ret that pops args */
! #define MASK_ALIGN_DOUBLE	000000000020	/* align doubles to 2 word boundary */
! #define MASK_SVR3_SHLIB		000000000040	/* Uninit locals into bss */
! #define MASK_IEEE_FP		000000000100	/* IEEE fp comparisons */
! #define MASK_FLOAT_RETURNS	000000000200	/* Return float in st(0) */
! #define MASK_NO_FANCY_MATH_387	000000000400	/* Disable sin, cos, sqrt */
! 
! 						/* Temporary codegen switches */
! #define MASK_DEBUG_ADDR		000001000000	/* Debug GO_IF_LEGITIMATE_ADDRESS */
! #define MASK_NO_WIDE_MULTIPLY	000002000000	/* Disable 32x32->64 multiplies */
! #define MASK_NO_MOVE		000004000000	/* Don't generate mem->mem */
! #define MASK_DEBUG_ARG		000010000000	/* Debug function_arg */   
! 
! /* Use the floating point instructions */
! #define TARGET_80387 (target_flags & MASK_80387)
! 
  /* Compile using ret insn that pops args.
     This will not work unless you use prototypes at least
     for all functions that can take varying numbers of args.  */  
! #define TARGET_RTD (target_flags & MASK_RTD)
  
  /* Align doubles to a two word boundary.  This breaks compatibility with
     the published ABI's for structures containing doubles, but produces
     faster code on the pentium.  */
! #define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE)
  
  /* Put uninitialized locals into bss, not data.
     Meaningful only on svr3.  */
! #define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB)
  
  /* Use IEEE floating point comparisons.  These handle correctly the cases
     where the result of a comparison is unordered.  Normally SIGFPE is
     generated in such cases, in which case this isn't needed.  */
! #define TARGET_IEEE_FP (target_flags & MASK_IEEE_FP)
  
  /* Functions that return a floating point value may return that value
     in the 387 FPU or in 386 integer registers.  If set, this flag causes
     the 387 to be used, which is compatible with most calling conventions. */
! #define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & MASK_FLOAT_RETURNS)
! 
! /* Disable generation of FP sin, cos and sqrt operations for 387.
!    This is because FreeBSD lacks these in the math-emulator-code */
! #define TARGET_NO_FANCY_MATH_387 (target_flags & MASK_NO_FANCY_MATH_387)
! 
! /* Temporary switches for tuning code generation */
! 
! /* Disable 32x32->64 bit multiplies that are used for long long multiplies
!    and division by constants, but sometimes cause reload problems.  */
! #define TARGET_NO_WIDE_MULTIPLY (target_flags & MASK_NO_WIDE_MULTIPLY)
! #define TARGET_WIDE_MULTIPLY (!TARGET_NO_WIDE_MULTIPLY)
! 
! /* Debug GO_IF_LEGITIMATE_ADDRESS */
! #define TARGET_DEBUG_ADDR (target_flags & MASK_DEBUG_ADDR)
  
  /* Debug FUNCTION_ARG macros */
! #define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
  
! /* Hack macros for tuning code generation */
! #define TARGET_MOVE	((target_flags & MASK_NO_MOVE) == 0)	/* Don't generate memory->memory */
  
! /* Specific hardware switches */
! #define TARGET_486	(target_flags & MASK_486)	/* 80486DX, 80486SX, 80486DX[24] */
! #define TARGET_386	(!TARGET_486) 			/* 80386 */
! 
! #define TARGET_SWITCHES							\
! { { "80387",			 MASK_80387 },				\
!   { "no-80387",			-MASK_80387 },				\
!   { "hard-float",		 MASK_80387 },				\
!   { "soft-float",		-MASK_80387 },				\
!   { "no-soft-float",		 MASK_80387 },				\
!   { "386",			-MASK_486 },				\
!   { "no-386",			 MASK_486 },				\
!   { "486",			 MASK_486 },				\
!   { "no-486",			-MASK_486 },				\
!   { "rtd",			 MASK_RTD },				\
!   { "no-rtd",			-MASK_RTD },				\
!   { "align-double",		 MASK_ALIGN_DOUBLE },			\
!   { "no-align-double",		-MASK_ALIGN_DOUBLE },			\
!   { "svr3-shlib",		 MASK_SVR3_SHLIB },			\
!   { "no-svr3-shlib",		-MASK_SVR3_SHLIB },			\
!   { "ieee-fp",			 MASK_IEEE_FP },			\
!   { "no-ieee-fp",		-MASK_IEEE_FP },			\
!   { "fp-ret-in-387",		 MASK_FLOAT_RETURNS },			\
!   { "no-fp-ret-in-387",		-MASK_FLOAT_RETURNS },			\
!   { "no-fancy-math-387",	 MASK_NO_FANCY_MATH_387 },		\
!   { "fancy-math-387",		-MASK_NO_FANCY_MATH_387 },		\
!   { "no-wide-multiply",		 MASK_NO_WIDE_MULTIPLY },		\
!   { "wide-multiply",		-MASK_NO_WIDE_MULTIPLY },		\
!   { "debug-addr",		 MASK_DEBUG_ADDR },			\
!   { "no-debug-addr",		-MASK_DEBUG_ADDR },			\
!   { "move",			-MASK_NO_MOVE },			\
!   { "no-move",			 MASK_NO_MOVE },			\
!   { "debug-arg",		 MASK_DEBUG_ARG },			\
!   { "no-debug-arg",		-MASK_DEBUG_ARG },			\
!   SUBTARGET_SWITCHES							\
!   { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
! 
! /* This macro is similar to `TARGET_SWITCHES' but defines names of
!    command options that have values.  Its definition is an
!    initializer with a subgrouping for each command option.
! 
!    Each subgrouping contains a string constant, that defines the
!    fixed part of the option name, and the address of a variable.  The
!    variable, type `char *', is set to the variable part of the given
!    option if the fixed part matches.  The actual option name is made
!    by appending `-m' to the specified name.  */
  #define TARGET_OPTIONS							\
  { { "reg-alloc=",	&i386_reg_alloc_order },			\
    { "regparm=",		&i386_regparm_string },				\
--- 59,196 ----
  /* Run-time compilation parameters selecting different hardware subsets.  */
  
  extern int target_flags;
+ /* Which processor to schedule for. intel1 */
+ 
+ enum processor_type {
+   PROCESSOR_DEFAULT,
+   PROCESSOR_386,
+   PROCESSOR_486,
+   PROCESSOR_PENTIUM
+ };
+ extern enum processor_type x86_cpu;	/* which cpu are we scheduling for */
+ 
+ /* intel1 */
+ #define REDUCE_INDEX (TARGET_486 || TARGET_PENTIUM)
+ #define SAVE_ON_REGS 1
+ #define MAX_DEST_ADDR_GIVS 5
+ #define PREFER_JUMP_NOT_TAKEN 1
+ #define PREFER_CONST_IN_REG 1
+ #define IGNORE_NON_DATA_DEP 1
+ #define STORE_NOT_SET_CC0 1
+ #define NO_CROSS_JUMP_ON_LOOP_ENTRY 1
+ #define AGI 1
+ /* #define SPILL1 */
+ #define EXPENSIVE_OPS(x) \
+    ( GET_CODE(x)==MULT ? \
+        ((GET_CODE (XEXP (x, 1)) == CONST_INT && \
+ 	exact_log2 (INTVAL (XEXP (x, 1))) >= 0) ? 0 : 1) : \
+ 	(GET_CODE(x)==DIV || GET_CODE(x)==UDIV || \
+ 	 GET_CODE(x)==MOD || GET_CODE(x)==UMOD ))
+ 
+ #define NO_STACK_REG_REORDER (!TARGET_PENTIUM)
+ 
+ #define STACK_REG_REORDER \
+ 	((TARGET_PENTIUM) && reload_completed == 0 && flag_schedule_stack_reg_insns)
+ 
+ #define STACK_NON_STACK_INTERLEAVE \
+ 	(reload_completed == 0 && flag_interleave_stack_non_stack)
+ 	
+ #define IS_RISC_MODE(mode) (((mode) == QImode || (mode) == SImode))
+ 
+ /* Number of extra pseudo registers we allocate for so that reg-stack
+    can replace fld's and fstps with movs
+ */
+ #define SPARE_REGS 5
+ #define OVERRIDE_OPTIONS override_options()
+ 
  
  /* Macros used in the machine description to test the flags.  */
  
  /* configure can arrange to make this 2, to force a 486.  */
  #ifndef TARGET_CPU_DEFAULT
! #define TARGET_CPU_DEFAULT TARGET_PENTIUM_SWITCH
  #endif
  
! /* Compile 80387 insns for floating point (not library calls).  */
! #define TARGET_80387 (target_flags & 1)
  /* Compile using ret insn that pops args.
     This will not work unless you use prototypes at least
     for all functions that can take varying numbers of args.  */  
! #define TARGET_RTD (target_flags & 8)
  
  /* Align doubles to a two word boundary.  This breaks compatibility with
     the published ABI's for structures containing doubles, but produces
     faster code on the pentium.  */
! #define TARGET_ALIGN_DOUBLE (target_flags & 020)
  
  /* Put uninitialized locals into bss, not data.
     Meaningful only on svr3.  */
! #define TARGET_SVR3_SHLIB (target_flags & 040)
  
  /* Use IEEE floating point comparisons.  These handle correctly the cases
     where the result of a comparison is unordered.  Normally SIGFPE is
     generated in such cases, in which case this isn't needed.  */
! #define TARGET_IEEE_FP (target_flags & 0100)
  
  /* Functions that return a floating point value may return that value
     in the 387 FPU or in 386 integer registers.  If set, this flag causes
     the 387 to be used, which is compatible with most calling conventions. */
! #define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & 0200)
  
  /* Debug FUNCTION_ARG macros */
! #define TARGET_DEBUG_ARG (target_flags & 000010000000)
! 
! /* Macro to define tables used to set the flags.
!    This is a list in braces of pairs in braces,
!    each pair being { "NAME", VALUE }
!    where VALUE is the bits to set or minus the bits to clear.
!    An empty string NAME is used to identify the default VALUE.  */
! 
! /* intel1 */
! #define TARGET_486_SWITCH 2
! #define TARGET_486 (target_flags & TARGET_486_SWITCH)
! /* Compile code for a Pentium. intel1 */
! #define TARGET_PENTIUM_SWITCH 4
! #define TARGET_PENTIUM (target_flags & TARGET_PENTIUM_SWITCH)
! /* Compile code for an i386. intel1 */
! #define TARGET_386_SWITCH 0400
! #define TARGET_386 (target_flags & TARGET_386_SWITCH)
! /* Compile code for a Blend. intel1 */
! #define TARGET_BLEND_SWITCH 02000
! #define TARGET_BLEND (target_flags & TARGET_BLEND_SWITCH)
! 
! #define TARGET_X ((TARGET_386) | (TARGET_486) | (TARGET_PENTIUM))
! #define USE_CPU ((TARGET_X) ? (TARGET_X) : TARGET_CPU_DEFAULT)
! 
! #define TARGET_SWITCHES  \
!   { { "80387", 1},				\
!     { "no-80387", -1},				\
!     { "soft-float", -1},			\
!     { "no-soft-float", 1},			\
!     { "486", 2},				\
!     { "no-486", -2},				\
!     { "386", 0400},				\
!     { "pentium", 4},				\
!     { "blend", 02000},				\
!     { "rtd", 8},				\
!     { "no-rtd", -8},				\
!     { "align-double", 020},				\
!     { "no-align-double", -020},			\
!     { "svr3-shlib", 040},			\
!     { "no-svr3-shlib", -040},			\
!     { "ieee-fp", 0100},				\
!     { "no-ieee-fp", -0100},			\
!     { "fp-ret-in-387", 0200},			\
!     { "no-fp-ret-in-387", -0200},		\
!     { "debug-addr", 000010000000 },			\
!     { "no-debug-addr", -000010000000},			\
!     SUBTARGET_SWITCHES                          \
!     { "", TARGET_DEFAULT }}
  
! /* This is meant to be redefined in the host dependent files */
! #define SUBTARGET_SWITCHES
  
! 
  #define TARGET_OPTIONS							\
  { { "reg-alloc=",	&i386_reg_alloc_order },			\
    { "regparm=",		&i386_regparm_string },				\
***************
*** 183,215 ****
    SUBTARGET_OPTIONS							\
  }
  
! /* Sometimes certain combinations of command options do not make
!    sense on a particular target machine.  You can define a macro
!    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
!    defined, is executed once just after all the command options have
!    been parsed.
  
!    Don't use this macro to turn on various extra optimizations for
!    `-O'.  That is what `OPTIMIZATION_OPTIONS' is for.  */
  
! #define OVERRIDE_OPTIONS override_options ()
  
- /* These are meant to be redefined in the host dependent files */
- #define SUBTARGET_SWITCHES
- #define SUBTARGET_OPTIONS
  
! 
  /* target machine storage layout */
  
  /* Define for XFmode extended real floating point support.
     This will automatically cause REAL_ARITHMETIC to be defined.  */
  #define LONG_DOUBLE_TYPE_SIZE 96
! 
  /* Define if you don't want extended real, but do want to use the
     software floating point emulator for REAL_ARITHMETIC and
     decimal <-> binary conversion. */
  /* #define REAL_ARITHMETIC */
  
  /* Define this if most significant byte of a word is the lowest numbered.  */
  /* That is true on the 80386.  */
  
--- 200,231 ----
    SUBTARGET_OPTIONS							\
  }
  
! #define SUBTARGET_OPTIONS
! /* intel1 */
  
! #define SUB_TARGET_STRING \
! (TARGET_PENTIUM ? "Pentium"  : (TARGET_386 ? "Intel386" : "Intel486"))
  
! #define SUB_TARGET_VERSION fprintf (stderr, " [%s cpu] ", SUB_TARGET_STRING)
  
  
! /* Define this to change the optimizations performed by default.  */
! 
! #define OPTIMIZATION_OPTIONS(LEVEL)	\
! optimization_options(LEVEL)
! 
  /* target machine storage layout */
  
  /* Define for XFmode extended real floating point support.
     This will automatically cause REAL_ARITHMETIC to be defined.  */
  #define LONG_DOUBLE_TYPE_SIZE 96
!  
  /* Define if you don't want extended real, but do want to use the
     software floating point emulator for REAL_ARITHMETIC and
     decimal <-> binary conversion. */
  /* #define REAL_ARITHMETIC */
  
+ 
  /* Define this if most significant byte of a word is the lowest numbered.  */
  /* That is true on the 80386.  */
  
***************
*** 265,270 ****
--- 281,289 ----
     aligned on 64 bit boundaries. */
  #define BIGGEST_ALIGNMENT (TARGET_ALIGN_DOUBLE ? 64 : 32)
  
+ /* intel1 - align DFmode constants and nonaggregates */
+ #define ALIGN_DFmode (!TARGET_386)
+ 
  /* Set this non-zero if move instructions will actually fail to work
     when given unaligned data.  */
  #define STRICT_ALIGNMENT 0
***************
*** 292,297 ****
--- 311,318 ----
     for details. */
  
  #define STACK_REGS
+ /* intel1 */
+ #define IS_STACK_MODE(mode) (mode==DFmode || mode==SFmode)
  
  /* Number of actual hardware registers.
     The hardware registers are assigned numbers for the compiler
***************
*** 329,372 ****
  /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
  {  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
  
- /* Order in which to allocate registers.  Each register must be
-    listed once, even those in FIXED_REGISTERS.  List frame pointer
-    late and fixed registers last.  Note that, in general, we prefer
-    registers listed in CALL_USED_REGISTERS, keeping the others
-    available for storage of persistent values.
- 
-    Three different versions of REG_ALLOC_ORDER have been tried:
- 
-    If the order is edx, ecx, eax, ... it produces a slightly faster compiler,
-    but slower code on simple functions returning values in eax.
- 
-    If the order is eax, ecx, edx, ... it causes reload to abort when compiling
-    perl 4.036 due to not being able to create a DImode register (to hold a 2
-    word union).
- 
-    If the order is eax, edx, ecx, ... it produces better code for simple
-    functions, and a slightly slower compiler.  Users complained about the code
-    generated by allocating edx first, so restore the 'natural' order of things. */
- 
- #define REG_ALLOC_ORDER \
- /*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
- {  0, 1, 2, 3, 4, 5, 6, 7, 8,  9, 10, 11, 12, 13, 14, 15, 16 }
- 
- /* A C statement (sans semicolon) to choose the order in which to
-    allocate hard registers for pseudo-registers local to a basic
-    block.
- 
-    Store the desired register order in the array `reg_alloc_order'.
-    Element 0 should be the register to allocate first; element 1, the
-    next register; and so on.
- 
-    The macro body should not assume anything about the contents of
-    `reg_alloc_order' before execution of the macro.
- 
-    On most machines, it is not necessary to define this macro.  */
- 
- #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
- 
  /* Macro to conditionally modify fixed_regs/call_used_regs.  */
  #define CONDITIONAL_REGISTER_USAGE			\
    {							\
--- 350,355 ----
***************
*** 408,413 ****
--- 391,399 ----
  /* The casts to int placate a compiler on a microvax,
     for cross-compiler testing.  */
  
+ /* intel1 - added case of (REGNO)==16 (gbug12)*/
+ /*   : (REGNO) == 16 ? 1                             \ */
+ 
  #define HARD_REGNO_MODE_OK(REGNO, MODE) \
    ((REGNO) < 2 ? 1						\
     : (REGNO) < 4 ? 1						\
***************
*** 479,505 ****
  /* Place in which caller passes the structure value address.
     0 means push the value on the stack like an argument.  */
  #define STRUCT_VALUE 0
- 
- /* A C expression which can inhibit the returning of certain function
-    values in registers, based on the type of value.  A nonzero value
-    says to return the function value in memory, just as large
-    structures are always returned.  Here TYPE will be a C expression
-    of type `tree', representing the data type of the value.
- 
-    Note that values of mode `BLKmode' must be explicitly handled by
-    this macro.  Also, the option `-fpcc-struct-return' takes effect
-    regardless of this macro.  On most systems, it is possible to
-    leave the macro undefined; this causes a default definition to be
-    used, whose value is the constant 1 for `BLKmode' values, and 0
-    otherwise.
- 
-    Do not use this macro to indicate that structures and unions
-    should always be returned in memory.  You should instead use
-    `DEFAULT_PCC_STRUCT_RETURN' to indicate this.  */
- 
- #define RETURN_IN_MEMORY(TYPE) \
-   ((TYPE_MODE (TYPE) == BLKmode) || int_size_in_bytes (TYPE) > 12)
- 
  
  /* Define the classes of registers for register constraints in the
     machine description.  Also define ranges of constants.
--- 465,470 ----
***************
*** 529,535 ****
  {
    NO_REGS,
    AREG, DREG, CREG, BREG,
-   AD_REGS,			/* %eax/%edx for DImode */
    Q_REGS,			/* %eax %ebx %ecx %edx */
    SIREG, DIREG,
    INDEX_REGS,			/* %eax %ebx %ecx %edx %esi %edi %ebp */
--- 494,499 ----
***************
*** 548,554 ****
  #define REG_CLASS_NAMES \
  {  "NO_REGS",				\
     "AREG", "DREG", "CREG", "BREG",	\
-    "AD_REGS",				\
     "Q_REGS",				\
     "SIREG", "DIREG",			\
     "INDEX_REGS",			\
--- 512,517 ----
***************
*** 564,573 ****
  #define REG_CLASS_CONTENTS \
  {      0,							\
       0x1,    0x2,  0x4,	 0x8,	/* AREG, DREG, CREG, BREG */	\
-      0x3,			/* AD_REGS */			\
       0xf,			/* Q_REGS */			\
      0x10,   0x20,		/* SIREG, DIREG */		\
!  0x07f,				/* INDEX_REGS */		\
   0x100ff,			/* GENERAL_REGS */		\
    0x0100, 0x0200,		/* FP_TOP_REG, FP_SECOND_REG */	\
    0xff00,			/* FLOAT_REGS */		\
--- 527,535 ----
  #define REG_CLASS_CONTENTS \
  {      0,							\
       0x1,    0x2,  0x4,	 0x8,	/* AREG, DREG, CREG, BREG */	\
       0xf,			/* Q_REGS */			\
      0x10,   0x20,		/* SIREG, DIREG */		\
!  0x1007f,			/* INDEX_REGS */		\
   0x100ff,			/* GENERAL_REGS */		\
    0x0100, 0x0200,		/* FP_TOP_REG, FP_SECOND_REG */	\
    0xff00,			/* FLOAT_REGS */		\
***************
*** 578,583 ****
--- 540,546 ----
     reg number REGNO.  This could be a conditional expression
     or could index an array.  */
  
+ extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
  #define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
  
  /* When defined, the compiler allows registers explicitly used in the
***************
*** 635,643 ****
     (C) == 'b' ? BREG :						\
     (C) == 'c' ? CREG :						\
     (C) == 'd' ? DREG :						\
-    (C) == 'A' ? AD_REGS :					\
     (C) == 'D' ? DIREG :						\
!    (C) == 'S' ? SIREG : NO_REGS)
  
  /* The letters I, J, K, L and M in a register constraint string
     can be used to stand for particular ranges of immediate operands.
--- 598,605 ----
     (C) == 'b' ? BREG :						\
     (C) == 'c' ? CREG :						\
     (C) == 'd' ? DREG :						\
     (C) == 'D' ? DIREG :						\
!    (C) == 'S' ? SIREG : NO_REGS) /* intel1 changed to e from S */
  
  /* The letters I, J, K, L and M in a register constraint string
     can be used to stand for particular ranges of immediate operands.
***************
*** 649,654 ****
--- 611,617 ----
     J is for DImode shifts.
     K and L are for an `andsi' optimization.
     M is for shifts that can be executed by the "lea" opcode.
+    O is for block moves intel1
     */
  
  #define CONST_OK_FOR_LETTER_P(VALUE, C)  \
***************
*** 657,662 ****
--- 620,626 ----
     (C) == 'K' ? (VALUE) == 0xff :		\
     (C) == 'L' ? (VALUE) == 0xffff :		\
     (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 :	\
+    (C) == 'O' ? (VALUE) >= 0 && (VALUE) <= 32 :	\
     (C) == 'N' ? (VALUE) >= 0 && (VALUE) <= 255 :\
     0)
  
***************
*** 710,742 ****
  #define CLASS_MAX_NREGS(CLASS, MODE)	\
   (FLOAT_CLASS_P (CLASS) ? 1 :		\
    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
  
! /* A C expression whose value is nonzero if pseudos that have been
!    assigned to registers of class CLASS would likely be spilled
!    because registers of CLASS are needed for spill registers.
! 
!    The default value of this macro returns 1 if CLASS has exactly one
!    register and zero otherwise.  On most machines, this default
!    should be used.  Only define this macro to some other expression
!    if pseudo allocated by `local-alloc.c' end up in memory because
!    their hard registers were needed for spill registers.  If this
!    macro returns nonzero for those classes, those pseudos will only
!    be allocated by `global.c', which knows how to reallocate the
!    pseudo to another register.  If there would not be another
!    register available for reallocation, you should not change the
!    definition of this macro since the only effect of such a
!    definition would be to slow down register allocation.  */
! 
! #define CLASS_LIKELY_SPILLED_P(CLASS)					\
!   (((CLASS) == AREG)							\
!    || ((CLASS) == DREG)							\
!    || ((CLASS) == CREG)							\
!    || ((CLASS) == BREG)							\
!    || ((CLASS) == AD_REGS)						\
!    || ((CLASS) == SIREG)						\
!    || ((CLASS) == DIREG))
  
- 
  /* Stack layout; function entry, exit and calling.  */
  
  /* Define this if pushing a word on the stack
--- 674,764 ----
  #define CLASS_MAX_NREGS(CLASS, MODE)	\
   (FLOAT_CLASS_P (CLASS) ? 1 :		\
    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ 
  
! /* A C statement (sans semicolon) to update the integer variable COST
!    based on the relationship between INSN that is dependent on
!    DEP_INSN through the dependence LINK.  The default is to make no
!    adjustment to COST.  */
! #define ADJUST_COST(insn,link,dep_insn,cost)				\
!   {									\
!     rtx next_inst;							\
!     if (GET_CODE (dep_insn) == CALL_INSN)				\
!       (cost) = 0;							\
!         if (GET_CODE (dep_insn) == INSN					\
!             && GET_CODE (PATTERN (dep_insn)) == SET			\
!             && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG		\
!             && GET_CODE (insn) == INSN					\
!             && GET_CODE (PATTERN (insn)) == SET				\
!             && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)),	\
!             	                         SET_SRC (PATTERN (insn))))	\
!           {								\
!             (cost) = 0;							\
!           }								\
!     if (GET_CODE (insn) == JUMP_INSN)					\
!       {									\
!         (cost) = 0;							\
!       }									\
!     if (TARGET_PENTIUM)							\
!       {									\
!         if (cost !=0 && is_fp_insn (insn) && is_fp_insn (dep_insn) 	\
!             && !is_fp_dest (dep_insn))					\
!           {								\
!             (cost) = 0;							\
!           }								\
!         if (agi_dependent (insn, dep_insn))				\
!           {								\
!             (cost) = 3;							\
!           }								\
!         else if (GET_CODE (insn) == INSN 				\
!                  && GET_CODE (PATTERN (insn)) == SET			\
!                  && SET_DEST (PATTERN (insn)) == cc0_rtx		\
!                  && (next_inst = next_nonnote_insn (insn))		\
!                  && GET_CODE (next_inst) == JUMP_INSN)			\
!           { /* compare probably paired with jump */			\
!             (cost) = 0;							\
!           }								\
!       }									\
!     else								\
!     if(!is_fp_dest (dep_insn))						\
!       {									\
!         if(!agi_dependent (insn, dep_insn))				\
!           (cost) = 0;							\
!          else if (TARGET_486)						\
!            (cost) = 2;							\
!       }									\
!     else								\
!     if(is_fp_store (insn) && is_fp_insn (dep_insn)			\
!        && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn))		\
!        && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))			\
!        && (GET_CODE (NEXT_INSN (insn)) == INSN)				\
!        && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN)	\
!        && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) 		\
!             == NOTE)							\
!        && NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) 	\
!            == NOTE_INSN_LOOP_END)					\
!       {									\
!            (cost) = 3;							\
!       }									\
!   }									
! 
! 
! #define ADJUST_BLOCKAGE(last_insn,insn,blockage)			\
!   {									\
!     if(is_fp_store (last_insn) && is_fp_insn (insn)			\
!        && NEXT_INSN (last_insn) && NEXT_INSN (NEXT_INSN (last_insn))	\
!        && NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn)))			\
!        && (GET_CODE (NEXT_INSN (last_insn)) == INSN)			\
!        && (GET_CODE (NEXT_INSN (NEXT_INSN (last_insn))) == JUMP_INSN)	\
!        && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn)))) 	\
!             == NOTE)							\
!        && NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (last_insn)))) 	\
!            == NOTE_INSN_LOOP_END)					\
!       {									\
!            (blockage) = 3;						\
!       }									\
!   }									
  
  /* Stack layout; function entry, exit and calling.  */
  
  /* Define this if pushing a word on the stack
***************
*** 887,988 ****
      }									\
  }
  
- /* A C statement or compound statement to output to FILE some
-    assembler code to initialize basic-block profiling for the current
-    object module.  This code should call the subroutine
-    `__bb_init_func' once per object module, passing it as its sole
-    argument the address of a block allocated in the object module.
- 
-    The name of the block is a local symbol made with this statement:
- 
- 	ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0);
- 
-    Of course, since you are writing the definition of
-    `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
-    can take a short cut in the definition of this macro and use the
-    name that you know will result.
- 
-    The first word of this block is a flag which will be nonzero if the
-    object module has already been initialized.  So test this word
-    first, and do not call `__bb_init_func' if the flag is nonzero.  */
- 
- #undef	FUNCTION_BLOCK_PROFILER
- #define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO)			\
- do									\
-   {									\
-     static int num_func = 0;						\
-     rtx xops[8];							\
-     char block_table[80], false_label[80];				\
- 									\
-     ASM_GENERATE_INTERNAL_LABEL (block_table, "LPBX", 0);		\
-     ASM_GENERATE_INTERNAL_LABEL (false_label, "LPBZ", num_func);	\
- 									\
-     xops[0] = const0_rtx;						\
-     xops[1] = gen_rtx (SYMBOL_REF, VOIDmode, block_table);		\
-     xops[2] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, false_label)); \
-     xops[3] = gen_rtx (MEM, Pmode, gen_rtx (SYMBOL_REF, VOIDmode, "__bb_init_func")); \
-     xops[4] = gen_rtx (MEM, Pmode, xops[1]);				\
-     xops[5] = stack_pointer_rtx;					\
-     xops[6] = GEN_INT (4);						\
-     xops[7] = gen_rtx (REG, Pmode, 0);	/* eax */			\
- 									\
-     CONSTANT_POOL_ADDRESS_P (xops[1]) = TRUE;				\
-     CONSTANT_POOL_ADDRESS_P (xops[2]) = TRUE;				\
- 									\
-     output_asm_insn (AS2(cmp%L4,%0,%4), xops);				\
-     output_asm_insn (AS1(jne,%2), xops);				\
- 									\
-     if (!flag_pic)							\
-       output_asm_insn (AS1(push%L1,%1), xops);				\
-     else								\
-       {									\
- 	output_asm_insn (AS2 (lea%L7,%a1,%7), xops);			\
- 	output_asm_insn (AS1 (push%L7,%7), xops);			\
-       }									\
- 									\
-     output_asm_insn (AS1(call,%P3), xops);				\
-     output_asm_insn (AS2(add%L0,%6,%5), xops);				\
-     ASM_OUTPUT_INTERNAL_LABEL (STREAM, "LPBZ", num_func);		\
-     num_func++;								\
-   }									\
- while (0)
- 
- 
- /* A C statement or compound statement to increment the count
-    associated with the basic block number BLOCKNO.  Basic blocks are
-    numbered separately from zero within each compilation.  The count
-    associated with block number BLOCKNO is at index BLOCKNO in a
-    vector of words; the name of this array is a local symbol made
-    with this statement:
- 
- 	ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2);
- 
-    Of course, since you are writing the definition of
-    `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you
-    can take a short cut in the definition of this macro and use the
-    name that you know will result.  */
- 
- #define BLOCK_PROFILER(STREAM, BLOCKNO)					\
- do									\
-   {									\
-     rtx xops[1], cnt_rtx;						\
-     char counts[80];							\
- 									\
-     ASM_GENERATE_INTERNAL_LABEL (counts, "LPBX", 2);			\
-     cnt_rtx = gen_rtx (SYMBOL_REF, VOIDmode, counts);			\
-     SYMBOL_REF_FLAG (cnt_rtx) = TRUE;					\
- 									\
-     if (BLOCKNO)							\
-       cnt_rtx = plus_constant (cnt_rtx, (BLOCKNO)*4);			\
- 									\
-     if (flag_pic)							\
-       cnt_rtx = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, cnt_rtx);	\
- 									\
-     xops[0] = gen_rtx (MEM, SImode, cnt_rtx);				\
-     output_asm_insn (AS1(inc%L0,%0), xops);				\
-   }									\
- while (0)
- 
  /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
     the stack pointer does not matter.  The value is tested only in
     functions that have frame pointers.
--- 909,914 ----
***************
*** 1146,1180 ****
     After reload, it makes no difference, since pseudo regs have
     been eliminated by then.  */
  
  
! /* Non strict versions, pseudos are ok */
! #define REG_OK_FOR_INDEX_NONSTRICT_P(X)					\
!   (REGNO (X) < STACK_POINTER_REGNUM					\
!    || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
! #define REG_OK_FOR_BASE_NONSTRICT_P(X)					\
!   (REGNO (X) <= STACK_POINTER_REGNUM					\
!    || REGNO (X) == ARG_POINTER_REGNUM					\
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
! #define REG_OK_FOR_STRREG_NONSTRICT_P(X)				\
    (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
! /* Strict versions, hard registers only */
! #define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
! #define REG_OK_FOR_BASE_STRICT_P(X)  REGNO_OK_FOR_BASE_P (REGNO (X))
! #define REG_OK_FOR_STRREG_STRICT_P(X)					\
!   (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X)))
  
! #ifndef REG_OK_STRICT
! #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_NONSTRICT_P(X)
! #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_NONSTRICT_P(X)
! #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_NONSTRICT_P(X)
  
- #else
- #define REG_OK_FOR_INDEX_P(X)  REG_OK_FOR_INDEX_STRICT_P(X)
- #define REG_OK_FOR_BASE_P(X)   REG_OK_FOR_BASE_STRICT_P(X)
- #define REG_OK_FOR_STRREG_P(X) REG_OK_FOR_STRREG_STRICT_P(X)
  #endif
  
  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
--- 1072,1107 ----
     After reload, it makes no difference, since pseudo regs have
     been eliminated by then.  */
  
+ #ifndef REG_OK_STRICT
  
! /* Nonzero if X is a hard reg that can be used as an index or if
!    it is a pseudo reg.  */
  
! #define REG_OK_FOR_INDEX_P(X) \
!   (REGNO (X) < STACK_POINTER_REGNUM \
     || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
! /* Nonzero if X is a hard reg that can be used as a base reg
!    of if it is a pseudo reg.  */
!   /* ?wfs */
! 
! #define REG_OK_FOR_BASE_P(X) \
!   (REGNO (X) <= STACK_POINTER_REGNUM \
!    || REGNO (X) == ARG_POINTER_REGNUM \
!    || REGNO(X) >= FIRST_PSEUDO_REGISTER)
! 
! #define REG_OK_FOR_STRREG_P(X) \
    (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
  
! #else
  
! /* Nonzero if X is a hard reg that can be used as an index.  */
! #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
! /* Nonzero if X is a hard reg that can be used as a base reg.  */
! #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
! #define REG_OK_FOR_STRREG_P(X) \
!   (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X)))
  
  #endif
  
  /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
***************
*** 1200,1221 ****
  
  #define LEGITIMATE_CONSTANT_P(X) 1
  
! #ifdef REG_OK_STRICT
! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
! {									\
!   if (legitimate_address_p (MODE, X, 1))				\
!     goto ADDR;								\
! }
  
! #else
! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)				\
  {									\
!   if (legitimate_address_p (MODE, X, 0))				\
      goto ADDR;								\
  }
  
- #endif
- 
  /* Try machine-dependent ways of modifying an illegitimate address
     to be legitimate.  If we find one, return the new, valid address.
     This macro is used in only one place: `memory_address' in explow.c.
--- 1127,1188 ----
  
  #define LEGITIMATE_CONSTANT_P(X) 1
  
! #define GO_IF_INDEXABLE_BASE(X, ADDR)	\
!  if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR
  
! #define LEGITIMATE_INDEX_REG_P(X)   \
!   (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
! 
! /* Return 1 if X is an index or an index times a scale.  */
! 
! #define LEGITIMATE_INDEX_P(X)   \
!    (LEGITIMATE_INDEX_REG_P (X)				\
!     || (GET_CODE (X) == MULT				\
! 	&& LEGITIMATE_INDEX_REG_P (XEXP (X, 0))		\
! 	&& GET_CODE (XEXP (X, 1)) == CONST_INT		\
! 	&& (INTVAL (XEXP (X, 1)) == 2			\
! 	    || INTVAL (XEXP (X, 1)) == 4		\
! 	    || INTVAL (XEXP (X, 1)) == 8)))
! 
! /* Go to ADDR if X is an index term, a base reg, or a sum of those.  */
! 
! #define GO_IF_INDEXING(X, ADDR)	\
! { if (LEGITIMATE_INDEX_P (X)) goto ADDR;				\
!   GO_IF_INDEXABLE_BASE (X, ADDR);					\
!   if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 0)))		\
!     { GO_IF_INDEXABLE_BASE (XEXP (X, 1), ADDR); }			\
!   if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 1)))		\
!     { GO_IF_INDEXABLE_BASE (XEXP (X, 0), ADDR); } }
! 
! /* We used to allow this, but it isn't ever used.
!    || ((GET_CODE (X) == POST_DEC || GET_CODE (X) == POST_INC)		\
!        && REG_P (XEXP (X, 0))						\
!        && REG_OK_FOR_STRREG_P (XEXP (X, 0)))				\
! */
! 
! #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)	\
  {									\
!   if (CONSTANT_ADDRESS_P (X)						\
!       && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (X)))			\
      goto ADDR;								\
+   GO_IF_INDEXING (X, ADDR);						\
+   if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1)))		\
+     {									\
+       rtx x0 = XEXP (X, 0);						\
+       if (! flag_pic || ! SYMBOLIC_CONST (XEXP (X, 1)))			\
+ 	{ GO_IF_INDEXING (x0, ADDR); }					\
+       else if (x0 == pic_offset_table_rtx)				\
+ 	goto ADDR;							\
+       else if (GET_CODE (x0) == PLUS)					\
+ 	{								\
+ 	  if (XEXP (x0, 0) == pic_offset_table_rtx)			\
+ 	    { GO_IF_INDEXABLE_BASE (XEXP (x0, 1), ADDR); }		\
+ 	  if (XEXP (x0, 1) == pic_offset_table_rtx)			\
+ 	    { GO_IF_INDEXABLE_BASE (XEXP (x0, 0), ADDR); }		\
+ 	}								\
+     }									\
  }
  
  /* Try machine-dependent ways of modifying an illegitimate address
     to be legitimate.  If we find one, return the new, valid address.
     This macro is used in only one place: `memory_address' in explow.c.
***************
*** 1237,1249 ****
     When -fpic is used, special handling is needed for symbolic references.
     See comments by legitimize_pic_address in i386.c for details.  */
  
! #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)				\
! {									\
!   rtx orig_x = (X);							\
!   (X) = legitimize_address (X, OLDX, MODE);				\
!   if (memory_address_p (MODE, X))					\
!     goto WIN;								\
! }
  
  /* Nonzero if the constant value X is a legitimate general operand
     when generating PIC code.  It is given that flag_pic is on and 
--- 1204,1244 ----
     When -fpic is used, special handling is needed for symbolic references.
     See comments by legitimize_pic_address in i386.c for details.  */
  
! #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)   \
! { extern rtx legitimize_pic_address ();					\
!   int ch = (X) != (OLDX);						\
!   if (flag_pic && SYMBOLIC_CONST (X))					\
!     {									\
!       (X) = legitimize_pic_address (X, 0);				\
!       if (memory_address_p (MODE, X))					\
! 	goto WIN;							\
!     }									\
!   if (GET_CODE (X) == PLUS)						\
!     { if (GET_CODE (XEXP (X, 0)) == MULT)				\
! 	ch = 1, XEXP (X, 0) = force_operand (XEXP (X, 0), 0);		\
!       if (GET_CODE (XEXP (X, 1)) == MULT)				\
! 	ch = 1, XEXP (X, 1) = force_operand (XEXP (X, 1), 0);		\
!       if (ch && GET_CODE (XEXP (X, 1)) == REG				\
! 	  && GET_CODE (XEXP (X, 0)) == REG)				\
! 	goto WIN;							\
!       if (flag_pic && SYMBOLIC_CONST (XEXP (X, 1)))			\
!         ch = 1, (X) = legitimize_pic_address (X, 0);			\
!       if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); }		\
!       if (GET_CODE (XEXP (X, 0)) == REG)                                \
! 	{ register rtx temp = gen_reg_rtx (Pmode);			\
! 	  register rtx val = force_operand (XEXP (X, 1), temp);		\
! 	  if (val != temp) emit_move_insn (temp, val);			\
! 	  XEXP (X, 1) = temp;						\
! 	  goto WIN; }							\
!       else if (GET_CODE (XEXP (X, 1)) == REG)				\
! 	{ register rtx temp = gen_reg_rtx (Pmode);			\
! 	  register rtx val = force_operand (XEXP (X, 0), temp);		\
! 	  if (val != temp) emit_move_insn (temp, val);			\
! 	  XEXP (X, 0) = temp;						\
! 	  goto WIN; }}}
! 
! /* intel1 */
! #define REWRITE_ADDRESS(x) rewrite_address(x)
  
  /* Nonzero if the constant value X is a legitimate general operand
     when generating PIC code.  It is given that flag_pic is on and 
***************
*** 1381,1386 ****
--- 1376,1385 ----
  /* Nonzero if access to memory by bytes is slow and undesirable.  */
  #define SLOW_BYTE_ACCESS 0
  
+ /* intel1 */
+ /* Nonzero if access to memory by shorts is slow and undesirable.  */
+ #define SLOW_SHORT_ACCESS 1
+ 
  /* Define if shifts truncate the shift count
     which implies one can omit a sign-extension or zero-extension
     of a shift count.  */
***************
*** 1512,1517 ****
--- 1511,1517 ----
     stored from the compare operation.  Note that we can't use "rtx" here
     since it hasn't been defined!  */
  
+ extern struct rtx_def *i386_compare_op0, *i386_compare_op1;
  extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
  
  /* Tell final.c how to eliminate redundant test instructions.  */
***************
*** 1519,1524 ****
--- 1519,1528 ----
  /* Here we define machine-dependent flags and fields in cc_status
     (see `conditions.h').  */
  
+ /* intel1 Set if the cc value is was actually from the 80387 and
+    we are testing eax directly (i.e. no sahf) */
+ #define CC_TEST_AX 020000
+ 
  /* Set if the cc value is actually in the 80387, so a floating point
     conditional branch must be output.  */
  #define CC_IN_80387 04000
***************
*** 1816,1827 ****
  	 { fputs ("argp", FILE); break; }		\
         if (STACK_TOP_P (X))				\
  	 { fputs ("st(0)", FILE); break; }		\
-        if (FP_REG_P (X))				\
- 	 { fputs (hi_name[REGNO(X)], FILE); break; }	\
         switch (GET_MODE_SIZE (GET_MODE (X)))		\
  	 {						\
! 	 default:					\
! 	   fputs ("e", FILE);				\
  	 case 2:					\
  	   fputs (hi_name[REGNO (X)], FILE);		\
  	   break;					\
--- 1820,1831 ----
  	 { fputs ("argp", FILE); break; }		\
         if (STACK_TOP_P (X))				\
  	 { fputs ("st(0)", FILE); break; }		\
         switch (GET_MODE_SIZE (GET_MODE (X)))		\
  	 {						\
! 	 case 12:					\
! 	 case 8:					\
! 	 case 4:					\
! 	   if (! FP_REG_P (X)) fputs ("e", FILE);	\
  	 case 2:					\
  	   fputs (hi_name[REGNO (X)], FILE);		\
  	   break;					\
***************
*** 1857,1865 ****
  #define RET return ""
  #define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
  
- /* Functions in i386.c */
- extern void override_options ();
- extern void order_regs_for_local_alloc ();
  extern int i386_valid_decl_attribute_p ();
  extern int i386_valid_type_attribute_p ();
  extern int i386_return_pops_args ();
--- 1861,1866 ----
***************
*** 1868,1909 ****
  extern void function_arg_advance ();
  extern struct rtx_def *function_arg ();
  extern int function_arg_partial_nregs ();
- extern void output_op_from_reg ();
- extern void output_to_reg ();
- extern char *singlemove_string ();
- extern char *output_move_double ();
- extern char *output_move_memory ();
- extern char *output_move_pushmem ();
- extern int standard_80387_constant_p ();
- extern char *output_move_const_single ();
- extern int symbolic_operand ();
- extern int call_insn_operand ();
- extern int expander_call_insn_operand ();
- extern int symbolic_reference_mentioned_p ();
- extern void emit_pic_move ();
- extern void function_prologue ();
- extern int simple_386_epilogue ();
- extern void function_epilogue ();
- extern int legitimate_address_p ();
- extern struct rtx_def *legitimize_pic_address ();
- extern struct rtx_def *legitimize_address ();
- extern void print_operand ();
- extern void print_operand_address ();
- extern void notice_update_cc ();
- extern void split_di ();
- extern int binary_387_op ();
- extern int shift_op ();
- extern int VOIDmode_compare_op ();
- extern char *output_387_binary_op ();
- extern char *output_fix_trunc ();
- extern char *output_float_compare ();
- extern char *output_fp_cc0_set ();
- extern void save_386_machine_status ();
- extern void restore_386_machine_status ();
- extern void clear_386_stack_locals ();
- extern struct rtx_def *assign_386_stack_local ();
  
! /* Variables in i386.c */
  extern char *i386_reg_alloc_order;		/* register allocation order */
  extern char *i386_regparm_string;		/* # registers to use to pass args */
  extern char *i386_align_loops_string;		/* power of two alignment for loops */
--- 1869,1876 ----
  extern void function_arg_advance ();
  extern struct rtx_def *function_arg ();
  extern int function_arg_partial_nregs ();
  
!   /* Variables in i386.c */
  extern char *i386_reg_alloc_order;		/* register allocation order */
  extern char *i386_regparm_string;		/* # registers to use to pass args */
  extern char *i386_align_loops_string;		/* power of two alignment for loops */
***************
*** 1913,1932 ****
  extern int i386_align_loops;			/* power of two alignment for loops */
  extern int i386_align_jumps;			/* power of two alignment for non-loop jumps */
  extern int i386_align_funcs;			/* power of two alignment for functions */
! extern char *hi_reg_name[];			/* names for 16 bit regs */
! extern char *qi_reg_name[];			/* names for 8 bit regs (low) */
! extern char *qi_high_reg_name[];		/* names for 8 bit regs (high) */
! extern enum reg_class regclass_map[];		/* smalled class containing REGNO */
! extern struct rtx_def *i386_compare_op0;	/* operand 0 for comparisons */
! extern struct rtx_def *i386_compare_op1;	/* operand 1 for comparisons */
! 
! /* External variables used */
! extern int optimize;			/* optimization level */
! extern int obey_regdecls;		/* TRUE if stupid register allocation */
! 
! /* External functions used */
! extern struct rtx_def *force_operand ();
! 
  /*
  Local variables:
  version-control: t
--- 1880,1888 ----
  extern int i386_align_loops;			/* power of two alignment for loops */
  extern int i386_align_jumps;			/* power of two alignment for non-loop jumps */
  extern int i386_align_funcs;			/* power of two alignment for functions */
! /*extern char *hi_reg_name[];			/* names for 16 bit regs */
! /*extern char *qi_reg_name[];			/* names for 8 bit regs (low) */
! /*extern char *qi_high_reg_name[];		/* names for 8 bit regs (high) */
  /*
  Local variables:
  version-control: t
diff -rNci gcc-2.7.2/config/i386/i386.md gcc-2.7.2p/config/i386/i386.md
*** gcc-2.7.2/config/i386/i386.md	Mon Aug 21 17:27:58 1995
--- gcc-2.7.2p/config/i386/i386.md	Tue Jan 23 09:35:00 1996
***************
*** 2,7 ****
--- 2,10 ----
  ;; Copyright (C) 1988, 1994, 1995 Free Software Foundation, Inc.
  ;; Mostly by William Schelter.
  
+ ;; Pentium cpu support and other enhancements by Tevi Devor Intel Corp.
+ ;; (tevi@iil.intel.com).
+ 
  ;; This file is part of GNU CC.
  
  ;; GNU CC is free software; you can redistribute it and/or modify
***************
*** 72,77 ****
--- 75,110 ----
  ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
  ;; after the tstM or cmp) will actually emit the tstM or cmpM.
  
+ ;intel1
+ (define_attr "type" "fld,integer,fpop,fpdiv"
+   (const_string "integer"))
+ 
+ ;; Functional units intel1
+ (define_function_unit "fp" 1 0
+  (and (eq_attr "type" "fpop") 
+       (ne (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_PENTIUM")))
+  5 5)
+ 
+ (define_function_unit "fp" 1 0
+  (and (eq_attr "type" "fpop") 
+       (eq (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_PENTIUM")))
+  3 0)
+ 
+ (define_function_unit "fp" 1 0
+  (eq_attr "type" "fpdiv") 
+  10 10)
+ 
+ (define_function_unit "fp" 1 0
+  (eq_attr "type" "fld") 
+  1 0)
+ 
+ (define_function_unit "integer" 1 0
+  (and (eq_attr "type" "integer") 
+       (ne (symbol_ref "x86_cpu") (symbol_ref "PROCESSOR_386")))
+  2 0)
+ 
+ 
+ 
  (define_insn "tstsi_1"
    [(set (cc0)
  	(match_operand:SI 0 "nonimmediate_operand" "rm"))]
***************
*** 144,247 ****
    DONE;
  }")
  
! (define_insn "tstsf_cc"
!   [(set (cc0)
! 	(match_operand:SF 0 "register_operand" "f"))
!    (clobber (match_scratch:HI 1 "=a"))]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "*
! {
!   if (! STACK_TOP_P (operands[0]))
!     abort ();
! 
!   output_asm_insn (\"ftst\", operands);
! 
!   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
!     output_asm_insn (AS1 (fstp,%y0), operands);
! 
!   return output_fp_cc0_set (insn);
! }")
! 
! ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
! ;; isn't IEEE compliant.
! 
! (define_expand "tstsf"
!   [(parallel [(set (cc0)
! 		   (match_operand:SF 0 "register_operand" ""))
! 	      (clobber (match_scratch:HI 1 ""))])]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "
! {
!   i386_compare_gen = gen_tstsf_cc;
!   i386_compare_op0 = operands[0];
!   DONE;
! }")
! 
! (define_insn "tstdf_cc"
!   [(set (cc0)
! 	(match_operand:DF 0 "register_operand" "f"))
!    (clobber (match_scratch:HI 1 "=a"))]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "*
! {
!   if (! STACK_TOP_P (operands[0]))
!     abort ();
! 
!   output_asm_insn (\"ftst\", operands);
! 
!   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
!     output_asm_insn (AS1 (fstp,%y0), operands);
! 
!   return output_fp_cc0_set (insn);
! }")
! 
! ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
! ;; isn't IEEE compliant.
! 
! (define_expand "tstdf"
!   [(parallel [(set (cc0)
! 		   (match_operand:DF 0 "register_operand" ""))
! 	      (clobber (match_scratch:HI 1 ""))])]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "
! {
!   i386_compare_gen = gen_tstdf_cc;
!   i386_compare_op0 = operands[0];
!   DONE;
! }")
! 
! (define_insn "tstxf_cc"
!   [(set (cc0)
! 	(match_operand:XF 0 "register_operand" "f"))
!    (clobber (match_scratch:HI 1 "=a"))]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "*
! {
!   if (! STACK_TOP_P (operands[0]))
!     abort ();
! 
!   output_asm_insn (\"ftst\", operands);
! 
!   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
!     output_asm_insn (AS1 (fstp,%y0), operands);
! 
!   return output_fp_cc0_set (insn);
! }")
! 
! ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
! ;; isn't IEEE compliant.
! 
! (define_expand "tstxf"
!   [(parallel [(set (cc0)
! 		   (match_operand:XF 0 "register_operand" ""))
! 	      (clobber (match_scratch:HI 1 ""))])]
!   "TARGET_80387 && ! TARGET_IEEE_FP"
!   "
! {
!   i386_compare_gen = gen_tstxf_cc;
!   i386_compare_op0 = operands[0];
!   DONE;
! }")
  
  ;;- compare instructions.  See comments above tstM patterns about
  ;;  expansion of these insns.
--- 177,281 ----
    DONE;
  }")
  
! ;; intel1
! ;;(define_insn "tstsf_cc"
! ;;  [(set (cc0)
! ;;	(match_operand:SF 0 "register_operand" "f"))
! ;;   (clobber (match_scratch:HI 1 "=a"))]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "*
! ;;{
! ;;  if (! STACK_TOP_P (operands[0]))
! ;;    abort ();
! ;;
! ;;  output_asm_insn (\"ftst\", operands);
! ;;
! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
! ;;
! ;;  return (char *) output_fp_cc0_set (insn);
! ;;}")
! ;;
! ;;;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode
! ;;;; isn't IEEE compliant.
! ;;
! ;;(define_expand "tstsf"
! ;;  [(parallel [(set (cc0)
! ;;		   (match_operand:SF 0 "register_operand" ""))
! ;;	      (clobber (match_scratch:HI 1 ""))])]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "
! ;;{
! ;;  i386_compare_gen = gen_tstsf_cc;
! ;;  i386_compare_op0 = operands[0];
! ;;  DONE;
! ;;}")
! ;;
! ;;(define_insn "tstdf_cc"
! ;;  [(set (cc0)
! ;;	(match_operand:DF 0 "register_operand" "f"))
! ;;   (clobber (match_scratch:HI 1 "=a"))]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "*
! ;;{
! ;;  if (! STACK_TOP_P (operands[0]))
! ;;    abort ();
! ;;
! ;;  output_asm_insn (\"ftst\", operands);
! ;;
! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
! ;;
! ;;  return (char *) output_fp_cc0_set (insn);
! ;;}")
! ;;
! ;;;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
! ;;;; isn't IEEE compliant.
! ;;
! ;;(define_expand "tstdf"
! ;;  [(parallel [(set (cc0)
! ;;		   (match_operand:DF 0 "register_operand" ""))
! ;;	      (clobber (match_scratch:HI 1 ""))])]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "
! ;;{
! ;;  i386_compare_gen = gen_tstdf_cc;
! ;;  i386_compare_op0 = operands[0];
! ;;  DONE;
! ;;}")
! 
! ;;(define_insn "tstxf_cc"
! ;;  [(set (cc0)
! ;;      (match_operand:XF 0 "register_operand" "f"))
! ;;   (clobber (match_scratch:HI 1 "=a"))]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "*
! ;;{
! ;;  if (! STACK_TOP_P (operands[0]))
! ;;    abort ();
! ;;
! ;;  output_asm_insn (\"ftst\", operands);
! ;;
! ;;  if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
! ;;    output_asm_insn (AS1 (fstp,%y0), operands);
! ;;
! ;;  return (char *) output_fp_cc0_set (insn);
! ;;}")
! ;;
! ;;;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode
! ;;;; isn't IEEE compliant.
! ;;
! ;;(define_expand "tstxf"
! ;;  [(parallel [(set (cc0)
! ;;                 (match_operand:XF 0 "register_operand" ""))
! ;;            (clobber (match_scratch:HI 1 ""))])]
! ;;  "TARGET_80387 && ! TARGET_IEEE_FP"
! ;;  "
! ;;{
! ;;  i386_compare_gen = gen_tstxf_cc;
! ;;  i386_compare_op0 = operands[0];
! ;;  DONE;
! ;;}")
  
  ;;- compare instructions.  See comments above tstM patterns about
  ;;  expansion of these insns.
***************
*** 343,397 ****
  ;; SFmode, there is the normal insn, and an insn where the second operand
  ;; is converted to the desired mode.
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
! 			[(match_operand:XF 0 "nonimmediate_operand" "f")
! 			 (match_operand:XF 1 "nonimmediate_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float:XF
! 			  (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(float:XF
! 			  (match_operand:SI 0 "nonimmediate_operand" "rm"))
  			 (match_operand:XF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float_extend:XF
! 			  (match_operand:DF 1 "nonimmediate_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float_extend:XF
! 			  (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 377,432 ----
  ;; SFmode, there is the normal insn, and an insn where the second operand
  ;; is converted to the desired mode.
  
+ ;;intel1 operand 1 and 2 changed from nonimmediate_operand to general_operand
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
! 			[(match_operand:XF 0 "general_operand" "f")
! 			 (match_operand:XF 1 "general_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float:XF
! 			  (match_operand:SI 1 "general_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(float:XF
! 			  (match_operand:SI 0 "general_operand" "rm"))
  			 (match_operand:XF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float_extend:XF
! 			  (match_operand:DF 1 "general_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:XF 0 "register_operand" "f")
  			 (float_extend:XF
! 			  (match_operand:SF 1 "general_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 399,415 ****
  			(match_operand:XF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
! 			[(match_operand:DF 0 "nonimmediate_operand" "f,fm")
! 			 (match_operand:DF 1 "nonimmediate_operand" "fm,f")]))
     (clobber (match_scratch:HI 3 "=a,a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 434,450 ----
  			(match_operand:XF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
! 			[(match_operand:DF 0 "general_operand" "f,fm")
! 			 (match_operand:DF 1 "general_operand" "fm,f")]))
     (clobber (match_scratch:HI 3 "=a,a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 419,425 ****
  			  (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 454,460 ----
  			  (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 429,435 ****
  			 (match_operand:DF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 464,470 ----
  			 (match_operand:DF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 439,445 ****
  			  (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 474,480 ----
  			  (match_operand:SF 1 "nonimmediate_operand" "fm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 449,455 ****
  			 (match_operand:DF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 484,501 ----
  			 (match_operand:DF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
! 
! ;;intel1 
! (define_insn ""
!   [(set (cc0)
! 	(match_operator 2 "VOIDmode_compare_op"
! 			[(float_extend:DF
! 			  (match_operand:SF 0 "register_operand" "f"))
! 			 (match_operand:DF 1 "general_operand" "fm")]))
!    (clobber (match_scratch:HI 3 "=a"))]
!   "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 457,463 ****
  			(match_operand:DF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  ;; These two insns will never be generated by combine due to the mode of
  ;; the COMPARE.
--- 503,509 ----
  			(match_operand:DF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  ;; These two insns will never be generated by combine due to the mode of
  ;; the COMPARE.
***************
*** 468,474 ****
  ;			 (match_operand:SF 1 "register_operand" "f"))))
  ;   (clobber (match_scratch:HI 2 "=a"))]
  ;  "TARGET_80387"
! ;  "* return output_float_compare (insn, operands);")
  ;
  ;(define_insn ""
  ;  [(set (cc0)
--- 514,520 ----
  ;			 (match_operand:SF 1 "register_operand" "f"))))
  ;   (clobber (match_scratch:HI 2 "=a"))]
  ;  "TARGET_80387"
! ;  "* return (char *) output_float_compare (insn, operands);")
  ;
  ;(define_insn ""
  ;  [(set (cc0)
***************
*** 477,493 ****
  ;			(match_operand:DF 1 "register_operand" "f")))
  ;   (clobber (match_scratch:HI 2 "=a"))]
  ;  "TARGET_80387"
! ;  "* return output_float_compare (insn, operands);")
  
  (define_insn "cmpsf_cc_1"
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:SF 0 "nonimmediate_operand" "f,fm")
! 			 (match_operand:SF 1 "nonimmediate_operand" "fm,f")]))
     (clobber (match_scratch:HI 3 "=a,a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 523,540 ----
  ;			(match_operand:DF 1 "register_operand" "f")))
  ;   (clobber (match_scratch:HI 2 "=a"))]
  ;  "TARGET_80387"
! ;  "* return (char *) output_float_compare (insn, operands);")
  
+ ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  (define_insn "cmpsf_cc_1"
    [(set (cc0)
  	(match_operator 2 "VOIDmode_compare_op"
  			[(match_operand:SF 0 "nonimmediate_operand" "f,fm")
! 			 (match_operand:SF 1 "general_operand" "fm,f")]))
     (clobber (match_scratch:HI 3 "=a,a"))]
    "TARGET_80387
     && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 497,503 ****
  			  (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 544,550 ----
  			  (match_operand:SI 1 "nonimmediate_operand" "rm"))]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 507,513 ****
  			 (match_operand:SF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
--- 554,560 ----
  			 (match_operand:SF 1 "register_operand" "f")]))
     (clobber (match_scratch:HI 3 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_insn ""
    [(set (cc0)
***************
*** 515,526 ****
  			(match_operand:SF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return output_float_compare (insn, operands);")
  
  (define_expand "cmpxf"
    [(set (cc0)
! 	(compare (match_operand:XF 0 "register_operand" "")
! 		 (match_operand:XF 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "
  {
--- 562,573 ----
  			(match_operand:SF 1 "register_operand" "f")))
     (clobber (match_scratch:HI 2 "=a"))]
    "TARGET_80387"
!   "* return (char *) output_float_compare (insn, operands);")
  
  (define_expand "cmpxf"
    [(set (cc0)
!       (compare (match_operand:XF 0 "register_operand" "")
!                (match_operand:XF 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "
  {
***************
*** 531,540 ****
    DONE;
  }")
  
  (define_expand "cmpdf"
    [(set (cc0)
  	(compare (match_operand:DF 0 "register_operand" "")
! 		 (match_operand:DF 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "
  {
--- 578,588 ----
    DONE;
  }")
  
+ ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  (define_expand "cmpdf"
    [(set (cc0)
  	(compare (match_operand:DF 0 "register_operand" "")
! 		 (match_operand:DF 1 "general_operand" "")))]
    "TARGET_80387"
    "
  {
***************
*** 545,554 ****
    DONE;
  }")
  
  (define_expand "cmpsf"
    [(set (cc0)
  	(compare (match_operand:SF 0 "register_operand" "")
! 		 (match_operand:SF 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "
  {
--- 593,603 ----
    DONE;
  }")
  
+ ;;intel1 operand 1 changed from nonimmediate_operand to general_operand
  (define_expand "cmpsf"
    [(set (cc0)
  	(compare (match_operand:SF 0 "register_operand" "")
! 		 (match_operand:SF 1 "general_operand" "")))]
    "TARGET_80387"
    "
  {
***************
*** 561,577 ****
  
  (define_expand "cmpxf_cc"
    [(parallel [(set (cc0)
! 		   (compare (match_operand:XF 0 "register_operand" "")
! 			    (match_operand:XF 1 "register_operand" "")))
! 	      (clobber (match_scratch:HI 2 ""))])]
    "TARGET_80387"
    "")
  
  (define_expand "cmpxf_ccfpeq"
    [(parallel [(set (cc0)
! 		   (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
! 				   (match_operand:XF 1 "register_operand" "")))
! 	      (clobber (match_scratch:HI 2 ""))])]
    "TARGET_80387"
    "
  {
--- 610,626 ----
  
  (define_expand "cmpxf_cc"
    [(parallel [(set (cc0)
!                  (compare (match_operand:XF 0 "register_operand" "")
!                           (match_operand:XF 1 "register_operand" "")))
!             (clobber (match_scratch:HI 2 ""))])]
    "TARGET_80387"
    "")
  
  (define_expand "cmpxf_ccfpeq"
    [(parallel [(set (cc0)
!                  (compare:CCFPEQ (match_operand:XF 0 "register_operand" "")
!                                  (match_operand:XF 1 "register_operand" "")))
!             (clobber (match_scratch:HI 2 ""))])]
    "TARGET_80387"
    "
  {
***************
*** 742,748 ****
  (define_insn ""
    [(set (match_operand:SI 0 "push_operand" "=<")
  	(match_operand:SI 1 "general_operand" "g"))]
!   "TARGET_386"
    "push%L0 %1")
  
  ;; On a 486, it is faster to move MEM to a REG and then push, rather than
--- 791,797 ----
  (define_insn ""
    [(set (match_operand:SI 0 "push_operand" "=<")
  	(match_operand:SI 1 "general_operand" "g"))]
!   "! TARGET_486"
    "push%L0 %1")
  
  ;; On a 486, it is faster to move MEM to a REG and then push, rather than
***************
*** 750,763 ****
  
  (define_insn ""
    [(set (match_operand:SI 0 "push_operand" "=<")
- 	(match_operand:SI 1 "nonmemory_operand" "ri"))]
-   "!TARGET_386 && TARGET_MOVE"
-   "push%L0 %1")
- 
- (define_insn ""
-   [(set (match_operand:SI 0 "push_operand" "=<")
  	(match_operand:SI 1 "general_operand" "ri"))]
!   "!TARGET_386 && !TARGET_MOVE"
    "push%L0 %1")
  
  ;; General case of fullword move.
--- 799,806 ----
  
  (define_insn ""
    [(set (match_operand:SI 0 "push_operand" "=<")
  	(match_operand:SI 1 "general_operand" "ri"))]
!   "TARGET_486"
    "push%L0 %1")
  
  ;; General case of fullword move.
***************
*** 775,789 ****
  
    if (flag_pic && SYMBOLIC_CONST (operands[1]))
      emit_pic_move (operands, SImode);
- 
-   /* Don't generate memory->memory moves, go through a register */
-   else if (TARGET_MOVE
- 	   && (reload_in_progress | reload_completed) == 0
- 	   && GET_CODE (operands[0]) == MEM
- 	   && GET_CODE (operands[1]) == MEM)
-     {
-       operands[1] = force_reg (SImode, operands[1]);
-     }
  }")
  
  ;; On i486, incl reg is faster than movl $1,reg.
--- 818,823 ----
***************
*** 791,797 ****
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=g,r")
  	(match_operand:SI 1 "general_operand" "ri,m"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    rtx link;
--- 825,831 ----
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=g,r")
  	(match_operand:SI 1 "general_operand" "ri,m"))]
!   ""
    "*
  {
    rtx link;
***************
*** 810,861 ****
      /* Fastest way to change a 0 to a 1.  */
      return AS1 (inc%L0,%0);
  
-   if (flag_pic && SYMBOLIC_CONST (operands[1]))
-     return AS2 (lea%L0,%a1,%0);
- 
    return AS2 (mov%L0,%1,%0);
  }")
  
  (define_insn ""
    [(set (match_operand:HI 0 "push_operand" "=<")
  	(match_operand:HI 1 "general_operand" "g"))]
!   "TARGET_386"
!   "push%W0 %1")
! 
! (define_insn ""
!   [(set (match_operand:HI 0 "push_operand" "=<")
! 	(match_operand:HI 1 "nonmemory_operand" "ri"))]
!   "!TARGET_386 && TARGET_MOVE"
!   "push%W0 %1")
! 
! (define_insn ""
!   [(set (match_operand:HI 0 "push_operand" "=<")
! 	(match_operand:HI 1 "general_operand" "ri"))]
!   "!TARGET_386 && !TARGET_MOVE"
    "push%W0 %1")
  
  ;; On i486, an incl and movl are both faster than incw and movw.
  
! (define_expand "movhi"
!   [(set (match_operand:HI 0 "general_operand" "")
! 	(match_operand:HI 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Don't generate memory->memory moves, go through a register */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
!     {
!       operands[1] = force_reg (HImode, operands[1]);
!     }
! }")
! 
! (define_insn ""
    [(set (match_operand:HI 0 "general_operand" "=g,r")
  	(match_operand:HI 1 "general_operand" "ri,m"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    rtx link;
--- 844,864 ----
      /* Fastest way to change a 0 to a 1.  */
      return AS1 (inc%L0,%0);
  
    return AS2 (mov%L0,%1,%0);
  }")
  
  (define_insn ""
    [(set (match_operand:HI 0 "push_operand" "=<")
  	(match_operand:HI 1 "general_operand" "g"))]
!   ""
    "push%W0 %1")
  
  ;; On i486, an incl and movl are both faster than incw and movw.
  
! (define_insn "movhi"
    [(set (match_operand:HI 0 "general_operand" "=g,r")
  	(match_operand:HI 1 "general_operand" "ri,m"))]
!   ""
    "*
  {
    rtx link;
***************
*** 885,910 ****
    return AS2 (mov%W0,%1,%0);
  }")
  
! (define_expand "movstricthi"
!   [(set (strict_low_part (match_operand:HI 0 "general_operand" ""))
! 	(match_operand:HI 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Don't generate memory->memory moves, go through a register */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
!     {
!       operands[1] = force_reg (HImode, operands[1]);
!     }
! }")
! 
! (define_insn ""
    [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  	(match_operand:HI 1 "general_operand" "ri,m"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    rtx link;
--- 888,897 ----
    return AS2 (mov%W0,%1,%0);
  }")
  
! (define_insn "movstricthi"
    [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
  	(match_operand:HI 1 "general_operand" "ri,m"))]
!   ""
    "*
  {
    rtx link;
***************
*** 932,955 ****
  ;; the amount pushed up to a halfword.
  (define_insn ""
    [(set (match_operand:QI 0 "push_operand" "=<")
! 	(match_operand:QI 1 "immediate_operand" "n"))]
    ""
-   "* return AS1 (push%W0,%1);")
- 
- (define_insn ""
-   [(set (match_operand:QI 0 "push_operand" "=<")
- 	(match_operand:QI 1 "nonimmediate_operand" "q"))]
-   "!TARGET_MOVE"
-   "*
- {
-   operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
-   return AS1 (push%W0,%1);
- }")
- 
- (define_insn ""
-   [(set (match_operand:QI 0 "push_operand" "=<")
- 	(match_operand:QI 1 "register_operand" "q"))]
-   "TARGET_MOVE"
    "*
  {
    operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
--- 919,926 ----
  ;; the amount pushed up to a halfword.
  (define_insn ""
    [(set (match_operand:QI 0 "push_operand" "=<")
! 	(match_operand:QI 1 "general_operand" "q"))]
    ""
    "*
  {
    operands[1] = gen_rtx (REG, HImode, REGNO (operands[1]));
***************
*** 961,986 ****
  ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  ;; or writes %ah, %bh, %ch, %dh.
  
! (define_expand "movqi"
!   [(set (match_operand:QI 0 "general_operand" "")
! 	(match_operand:QI 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Don't generate memory->memory moves, go through a register */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
!     {
!       operands[1] = force_reg (QImode, operands[1]);
!     }
! }")
! 
! (define_insn ""
    [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  	(match_operand:QI 1 "general_operand" "*g,q,qn"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    rtx link;
--- 932,941 ----
  ;; ??? Do a recognizer for zero_extract that looks just like this, but reads
  ;; or writes %ah, %bh, %ch, %dh.
  
! (define_insn "movqi"
    [(set (match_operand:QI 0 "general_operand" "=q,*r,qm")
  	(match_operand:QI 1 "general_operand" "*g,q,qn"))]
!   ""
    "*
  {
    rtx link;
***************
*** 1015,1040 ****
  ;; If operands[1] is a constant, then an andl/orl sequence would be
  ;; faster.
  
! (define_expand "movstrictqi"
!   [(set (strict_low_part (match_operand:QI 0 "general_operand" ""))
! 	(match_operand:QI 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Don't generate memory->memory moves, go through a register */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && GET_CODE (operands[1]) == MEM)
!     {
!       operands[1] = force_reg (QImode, operands[1]);
!     }
! }")
! 
! (define_insn ""
    [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  	(match_operand:QI 1 "general_operand" "*qn,m"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    rtx link;
--- 970,979 ----
  ;; If operands[1] is a constant, then an andl/orl sequence would be
  ;; faster.
  
! (define_insn "movstrictqi"
    [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q"))
  	(match_operand:QI 1 "general_operand" "*qn,m"))]
!   ""
    "*
  {
    rtx link;
***************
*** 1063,1105 ****
    return AS2 (mov%B0,%1,%0);
  }")
  
! (define_expand "movsf"
!   [(set (match_operand:SF 0 "general_operand" "")
! 	(match_operand:SF 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Special case memory->memory moves and pushes */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], SFmode)))
!     {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], SFmode))
! 						? gen_movsf_push
! 						: gen_movsf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
!     }
! 
!   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
!      indicate we need the pic register loaded.  This could be optimized into stores
!      of constants if the target eventually moves to memory, but better safe than
!      sorry.  */
!   if (flag_pic
!       && GET_CODE (operands[0]) != MEM
!       && GET_CODE (operands[1]) == CONST_DOUBLE
!       && !standard_80387_constant_p (operands[1]))
!     {
!       current_function_uses_pic_offset_table = 1;
!     }
! }")
! 
! (define_insn "movsf_push_nomove"
    [(set (match_operand:SF 0 "push_operand" "=<,<")
  	(match_operand:SF 1 "general_operand" "gF,f"))]
!   "!TARGET_MOVE"
    "*
  {
    if (STACK_REG_P (operands[1]))
--- 1002,1011 ----
    return AS2 (mov%B0,%1,%0);
  }")
  
! (define_insn ""
    [(set (match_operand:SF 0 "push_operand" "=<,<")
  	(match_operand:SF 1 "general_operand" "gF,f"))]
!   ""
    "*
  {
    if (STACK_REG_P (operands[1]))
***************
*** 1124,1184 ****
    return AS1 (push%L1,%1);
  }")
  
! (define_insn "movsf_push"
!   [(set (match_operand:SF 0 "push_operand" "=<,<,<,<")
! 	(match_operand:SF 1 "general_operand" "rF,f,m,m"))
!    (clobber (match_scratch:SI 2 "=X,X,r,X"))]
!   ""
!   "*
! {
!   if (STACK_REG_P (operands[1]))
!     {
!       rtx xops[3];
! 
!       if (! STACK_TOP_P (operands[1]))
!         abort ();
! 
!       xops[0] = AT_SP (SFmode);
!       xops[1] = GEN_INT (4);
!       xops[2] = stack_pointer_rtx;
! 
!       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
! 
!       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
!         output_asm_insn (AS1 (fstp%S0,%0), xops);
!       else
!         output_asm_insn (AS1 (fst%S0,%0), xops);
!       RET;
!     }
! 
!   else if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != REG)
!     return AS1 (push%L1,%1);
! 
!   else
!     {
!       output_asm_insn (AS2 (mov%L2,%1,%2), operands);
!       return AS1 (push%L2,%2);
!     }
! }")
  
! ;; Special memory<->memory pattern that combine will recreate from the
! ;; moves to pseudos.
! (define_insn "movsf_mem"
!   [(set (match_operand:SF 0 "memory_operand" "=m")
! 	(match_operand:SF 1 "memory_operand" "m"))
!    (clobber (match_scratch:SI 2 "=&r"))]
    ""
    "*
  {
!   output_asm_insn (AS2 (mov%L2,%1,%2), operands);
!   return AS2 (mov%L0,%2,%0);
  }")
  
! ;; For the purposes of regclass, prefer FLOAT_REGS.
! (define_insn "movsf_normal"
    [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  	(match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1030,1053 ----
    return AS1 (push%L1,%1);
  }")
  
! ;; Allow MEM-MEM moves before reload.  The reload class for such a
! ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
! ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
  
! ;;intel1
! (define_insn "memmovsf"
!   [(set (match_operand:SF 0 "memory_operand" "=r,m")
! 	(match_operand:SF 1 "memory_operand" "m,r"))]
    ""
    "*
  {
!   return (char *) singlemove_string (operands);
  }")
  
! (define_insn "movsf"
    [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm")
  	(match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))]
!   ""
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
***************
*** 1220,1286 ****
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
      return AS1 (fld%z1,%y1);
  
    /* Handle all SFmode moves not involving the 387 */
  
!   return singlemove_string (operands);
! }")
! 
! (define_insn "swapsf"
!   [(set (match_operand:SF 0 "register_operand" "f")
! 	(match_operand:SF 1 "register_operand" "f"))
!    (set (match_dup 1)
! 	(match_dup 0))]
!   ""
!   "*
! {
!   if (STACK_TOP_P (operands[0]))
!     return AS1 (fxch,%1);
!   else
!     return AS1 (fxch,%0);
! }")
! 
! (define_expand "movdf"
!   [(set (match_operand:DF 0 "general_operand" "")
! 	(match_operand:DF 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Special case memory->memory moves and pushes */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], DFmode)))
!     {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], DFmode))
! 						? gen_movdf_push
! 						: gen_movdf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
!     }
! 
!   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
!      indicate we need the pic register loaded.  This could be optimized into stores
!      of constants if the target eventually moves to memory, but better safe than
!      sorry.  */
!   if (flag_pic
!       && GET_CODE (operands[0]) != MEM
!       && GET_CODE (operands[1]) == CONST_DOUBLE
!       && !standard_80387_constant_p (operands[1]))
!     {
!       current_function_uses_pic_offset_table = 1;
!     }
! }")
  
! (define_insn "movdf_push_nomove"
    [(set (match_operand:DF 0 "push_operand" "=<,<")
  	(match_operand:DF 1 "general_operand" "gF,f"))]
!   "!TARGET_MOVE"
    "*
  {
    if (STACK_REG_P (operands[1]))
--- 1089,1109 ----
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return (char *) output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
      return AS1 (fld%z1,%y1);
  
    /* Handle all SFmode moves not involving the 387 */
  
!   return (char *) singlemove_string (operands);
! }"[(set_attr "type" "fld")])
  
! ;;should change to handle the memory operands[1] without doing df push..
! (define_insn ""
    [(set (match_operand:DF 0 "push_operand" "=<,<")
  	(match_operand:DF 1 "general_operand" "gF,f"))]
!   ""
    "*
  {
    if (STACK_REG_P (operands[1]))
***************
*** 1301,1355 ****
        RET;
      }
    else
!     return output_move_double (operands);
  }")
  
! (define_insn "movdf_push"
!   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<")
! 	(match_operand:DF 1 "general_operand" "rF,f,o,o,o"))
!    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
!    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
    ""
    "*
  {
!   if (STACK_REG_P (operands[1]))
!     {
!       rtx xops[3];
! 
!       xops[0] = AT_SP (SFmode);
!       xops[1] = GEN_INT (8);
!       xops[2] = stack_pointer_rtx;
! 
!       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
! 
!       if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
!         output_asm_insn (AS1 (fstp%Q0,%0), xops);
!       else
!         output_asm_insn (AS1 (fst%Q0,%0), xops);
! 
!       RET;
!     }
! 
!   else if (GET_CODE (operands[1]) != MEM)
!     return output_move_double (operands);
! 
    else
!     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);
  }")
  
! (define_insn "movdf_mem"
!   [(set (match_operand:DF 0 "memory_operand" "=o,o")
! 	(match_operand:DF 1 "memory_operand" "o,o"))
!    (clobber (match_scratch:SI 2 "=&r,&r"))
!    (clobber (match_scratch:SI 3 "=&r,X"))]
    ""
!   "* return output_move_memory (operands, insn, GET_MODE_SIZE (DFmode), 2, 4);")
  
! ;; For the purposes of regclass, prefer FLOAT_REGS.
! (define_insn "movdf_normal"
!   [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
! 	(match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1124,1164 ----
        RET;
      }
    else
!     return (char *) output_move_double (operands);
  }")
  
! (define_insn "swapdf"
!   [(set (match_operand:DF 0 "register_operand" "f")
! 	(match_operand:DF 1 "register_operand" "f"))
!    (set (match_dup 1)
! 	(match_dup 0))]
    ""
    "*
  {
!   if (STACK_TOP_P (operands[0]))
!     return AS1 (fxch,%1);
    else
!     return AS1 (fxch,%0);
  }")
  
! ;; Allow MEM-MEM moves before reload.  The reload class for such a
! ;; move will be ALL_REGS.  PREFERRED_RELOAD_CLASS will narrow this to
! ;; GENERAL_REGS.  For the purposes of regclass, prefer FLOAT_REGS.
! 
! ;;intel1
! (define_insn "memmovdf"
!   [(set (match_operand:DF 0 "memory_operand" "=r,m")
! 	(match_operand:DF 1 "memory_operand" "m,r"))]
    ""
!   "*
! {
!   return (char *) output_move_double (operands);
! }")
  
! (define_insn "movdf"
!   [(set (match_operand:DF 0 "general_operand" "=*rfm,*rf,f,!*rm")
! 	(match_operand:DF 1 "general_operand" "*rf,*rfm,fG,fF"))]
!   ""
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
***************
*** 1391,1458 ****
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
      return AS1 (fld%z1,%y1);
  
    /* Handle all DFmode moves not involving the 387 */
  
!   return output_move_double (operands);
! }")
  
! (define_insn "swapdf"
!   [(set (match_operand:DF 0 "register_operand" "f")
! 	(match_operand:DF 1 "register_operand" "f"))
!    (set (match_dup 1)
! 	(match_dup 0))]
!   ""
!   "*
! {
!   if (STACK_TOP_P (operands[0]))
!     return AS1 (fxch,%1);
!   else
!     return AS1 (fxch,%0);
! }")
! 
! (define_expand "movxf"
!   [(set (match_operand:XF 0 "general_operand" "")
! 	(match_operand:XF 1 "general_operand" ""))]
!   ""
!   "
! {
!   /* Special case memory->memory moves and pushes */
!   if (TARGET_MOVE
!       && (reload_in_progress | reload_completed) == 0
!       && GET_CODE (operands[0]) == MEM
!       && (GET_CODE (operands[1]) == MEM || push_operand (operands[0], XFmode)))
!     {
!       rtx (*genfunc) PROTO((rtx, rtx)) = (push_operand (operands[0], XFmode))
! 						? gen_movxf_push
! 						: gen_movxf_mem;
! 
!       emit_insn ((*genfunc) (operands[0], operands[1]));
!       DONE;
!     }
! 
!   /* If we are loading a floating point constant that isn't 0 or 1 into a register,
!      indicate we need the pic register loaded.  This could be optimized into stores
!      of constants if the target eventually moves to memory, but better safe than
!      sorry.  */
!   if (flag_pic
!       && GET_CODE (operands[0]) != MEM
!       && GET_CODE (operands[1]) == CONST_DOUBLE
!       && !standard_80387_constant_p (operands[1]))
!     {
!       current_function_uses_pic_offset_table = 1;
!     }
! }")
! 
! 
! (define_insn "movxf_push_nomove"
    [(set (match_operand:XF 0 "push_operand" "=<,<")
   	(match_operand:XF 1 "general_operand" "gF,f"))]
!   "!TARGET_MOVE"
    "*
  {
    if (STACK_REG_P (operands[1]))
--- 1200,1219 ----
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return (char *) output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
      return AS1 (fld%z1,%y1);
  
    /* Handle all DFmode moves not involving the 387 */
  
!   return (char *) output_move_double (operands);
! }"[(set_attr "type" "fld")])
  
! (define_insn ""
    [(set (match_operand:XF 0 "push_operand" "=<,<")
   	(match_operand:XF 1 "general_operand" "gF,f"))]
!   ""
    "*
  {
    if (STACK_REG_P (operands[1]))
***************
*** 1471,1523 ****
        RET;
      }
    else
!     return output_move_double (operands);
   }")
  
! (define_insn "movxf_push"
!   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
!  	(match_operand:XF 1 "general_operand" "rF,f,o,o,o"))
!    (clobber (match_scratch:SI 2 "=X,X,&r,&r,X"))
!    (clobber (match_scratch:SI 3 "=X,X,&r,X,X"))]
    ""
    "*
  {
!   if (STACK_REG_P (operands[1]))
!     {
!       rtx xops[3];
! 
!       xops[0] = AT_SP (SFmode);
!       xops[1] = GEN_INT (12);
!       xops[2] = stack_pointer_rtx;
! 
!       output_asm_insn (AS2 (sub%L2,%1,%2), xops);
!       output_asm_insn (AS1 (fstp%T0,%0), xops);
!       if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
! 	output_asm_insn (AS1 (fld%T0,%0), xops);
! 
!       RET;
!     }
! 
!   else if (GET_CODE (operands[1]) != MEM
! 	   || GET_CODE (operands[2]) != REG)
!     return output_move_double (operands);
! 
    else
!     return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);
  }")
  
! (define_insn "movxf_mem"
!   [(set (match_operand:XF 0 "memory_operand" "=o,o")
! 	(match_operand:XF 1 "memory_operand" "o,o"))
!    (clobber (match_scratch:SI 2 "=&r,&r"))
!    (clobber (match_scratch:SI 3 "=&r,X"))]
!   ""
!   "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);")
! 
! (define_insn "movxf_normal"
    [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  	(match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
!   "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)"
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
--- 1232,1260 ----
        RET;
      }
    else
!     return (char *) output_move_double (operands);
   }")
  
! (define_insn "swapxf"
!   [(set (match_operand:XF 0 "register_operand" "f")
! 	(match_operand:XF 1 "register_operand" "f"))
!    (set (match_dup 1)
! 	(match_dup 0))]
    ""
    "*
  {
!   if (STACK_TOP_P (operands[0]))
!     return AS1 (fxch,%1);
    else
!     return AS1 (fxch,%0);
  }")
  
! (define_insn "movxf"
    [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm")
  	(match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
! ;;  [(set (match_operand:XF 0 "general_operand" "=*rf,*rfm,f,!*rm")
! ;;	(match_operand:XF 1 "general_operand" "*rfm,*rf,fG,fF"))]
!   ""
    "*
  {
    int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
***************
*** 1560,1620 ****
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
         return AS1 (fld%z1,%y1);
  
    /* Handle all XFmode moves not involving the 387 */
  
!   return output_move_double (operands);
! }")
! 
! (define_insn "swapxf"
!   [(set (match_operand:XF 0 "register_operand" "f")
! 	(match_operand:XF 1 "register_operand" "f"))
!    (set (match_dup 1)
! 	(match_dup 0))]
!   ""
!   "*
! {
!   if (STACK_TOP_P (operands[0]))
!     return AS1 (fxch,%1);
!   else
!     return AS1 (fxch,%0);
  }")
  
  (define_insn ""
!   [(set (match_operand:DI 0 "push_operand" "=<,<,<,<")
! 	(match_operand:DI 1 "general_operand" "riF,o,o,o"))
!    (clobber (match_scratch:SI 2 "=X,&r,&r,X"))
!    (clobber (match_scratch:SI 3 "=X,&r,X,X"))]
    ""
    "*
  {
!   if (GET_CODE (operands[1]) != MEM)
!     return output_move_double (operands);
! 
!   else
!     return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  }")
  
  (define_insn "movdi"
!   [(set (match_operand:DI 0 "general_operand" "=o,o,r,rm")
! 	(match_operand:DI 1 "general_operand" "o,o,m,riF"))
!    (clobber (match_scratch:SI 2 "=&r,&r,X,X"))
!    (clobber (match_scratch:SI 3 "=&r,X,X,X"))]
    ""
    "*
  {
!   rtx low[2], high[2], xop[6];
! 
!   if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
!     return output_move_double (operands);
!   else
!     return output_move_memory (operands, insn, GET_MODE_SIZE (DImode), 2, 4);
  }")
- 
  
  ;;- conversion instructions
  ;;- NONE
--- 1297,1329 ----
    /* Handle other kinds of reads to the 387 */
  
    if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE)
!     return (char *) output_move_const_single (operands);
  
    if (STACK_TOP_P (operands[0]))
         return AS1 (fld%z1,%y1);
  
    /* Handle all XFmode moves not involving the 387 */
  
!   return (char *) output_move_double (operands);
  }")
  
  (define_insn ""
!   [(set (match_operand:DI 0 "push_operand" "=<")
! 	(match_operand:DI 1 "general_operand" "roiF"))]
    ""
    "*
  {
!   return (char *) output_move_double (operands);
  }")
  
  (define_insn "movdi"
!   [(set (match_operand:DI 0 "general_operand" "=r,rm")
! 	(match_operand:DI 1 "general_operand" "m,riF"))]
    ""
    "*
  {
!   return (char *) output_move_double (operands);
  }")
  
  ;;- conversion instructions
  ;;- NONE
***************
*** 1629,1635 ****
    ""
    "*
  {
!   if ((!TARGET_386 || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
--- 1338,1344 ----
    ""
    "*
  {
!   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
***************
*** 1639,1644 ****
--- 1348,1372 ----
        RET;
      }
  
+   if ((((TARGET_486 || TARGET_PENTIUM))) 
+        && !reg_overlap_mentioned_p(operands[0],operands[1]))
+   {
+     rtx xops[2];
+       output_asm_insn (AS2 (xor%L0,%0,%0),operands);
+       output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
+     RET;
+   }
+ 
+   if ((TARGET_486 || TARGET_PENTIUM))
+   {
+     rtx xops[2];
+       xops[0] = operands[0];
+       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff);
+       output_asm_insn (AS2 (mov%W0,%1,%w0),operands);
+       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
+     RET;
+   }
+ 
  #ifdef INTEL_SYNTAX
    return AS2 (movzx,%1,%0);
  #else
***************
*** 1653,1659 ****
    ""
    "*
  {
!   if ((!TARGET_386 || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
--- 1381,1387 ----
    ""
    "*
  {
!   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
***************
*** 1663,1668 ****
--- 1391,1416 ----
        RET;
      }
  
+     /* intel1 */
+   if ((((TARGET_486 || TARGET_PENTIUM))) &&
+        reg_fits_class_p (operands[0], Q_REGS, 0, SImode))
+   {
+     rtx xops[2];
+     if(!reg_overlap_mentioned_p(operands[0],operands[1]))
+     {
+       output_asm_insn (AS2 (xor%L0,%k0,%k0),operands);
+       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
+     }
+     else
+     {
+       xops[0] = operands[0];
+       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
+       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
+       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
+     }
+     RET;
+   }
+ 
  #ifdef INTEL_SYNTAX
    return AS2 (movzx,%1,%0);
  #else
***************
*** 1677,1683 ****
    ""
    "*
  {
!   if ((!TARGET_386 || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
--- 1425,1431 ----
    ""
    "*
  {
!   if (((TARGET_486 || TARGET_PENTIUM) || REGNO (operands[0]) == 0)
        && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1]))
      {
        rtx xops[2];
***************
*** 1687,1692 ****
--- 1435,1471 ----
        RET;
      }
  
+     /* intel1 */
+   if ((((TARGET_486 || TARGET_PENTIUM))) &&
+        reg_fits_class_p (operands[0], Q_REGS, 0, SImode))
+   {
+     rtx xops[2];
+     if(!reg_overlap_mentioned_p(operands[0],operands[1]))
+     {
+       output_asm_insn (AS2 (xor%L0,%0,%0),operands);
+       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
+     }
+     else
+     {
+       xops[0] = operands[0];
+       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
+       output_asm_insn (AS2 (mov%B0,%1,%b0),operands);
+       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
+     }
+     RET;
+   }
+ 
+   if ((TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[1]) == REG)
+   {
+     rtx xops[2];
+       xops[0] = operands[0];
+       operands[1] = gen_rtx (REG, SImode, REGNO (operands[1]));
+       xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff);
+       output_asm_insn (AS2 (mov%L0,%1,%0),operands);
+       output_asm_insn (AS2 (and%L0,%1,%k0), xops);
+     RET;
+   }
+ 
  #ifdef INTEL_SYNTAX
    return AS2 (movzx,%1,%0);
  #else
***************
*** 2013,2027 ****
  
  (define_expand "fixuns_truncxfsi2"
    [(set (match_dup 4)
! 	(match_operand:XF 1 "register_operand" ""))
     (parallel [(set (match_dup 2)
! 		   (fix:DI (fix:XF (match_dup 4))))
! 	      (clobber (match_dup 4))
! 	      (clobber (match_dup 5))
! 	      (clobber (match_dup 6))
! 	      (clobber (match_scratch:SI 7 ""))])
     (set (match_operand:SI 0 "general_operand" "")
! 	(match_dup 3))]
    "TARGET_80387"
    "
  {
--- 1792,1806 ----
  
  (define_expand "fixuns_truncxfsi2"
    [(set (match_dup 4)
!       (match_operand:XF 1 "register_operand" ""))
     (parallel [(set (match_dup 2)
!                  (fix:DI (fix:XF (match_dup 4))))
!             (clobber (match_dup 4))
!             (clobber (match_dup 5))
!             (clobber (match_dup 6))
!             (clobber (match_scratch:SI 7 ""))])
     (set (match_operand:SI 0 "general_operand" "")
!       (match_dup 3))]
    "TARGET_80387"
    "
  {
***************
*** 2078,2090 ****
  
  (define_expand "fix_truncxfdi2"
    [(set (match_dup 2)
! 	(match_operand:XF 1 "register_operand" ""))
     (parallel [(set (match_operand:DI 0 "general_operand" "")
! 		   (fix:DI (fix:XF (match_dup 2))))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_dup 4))
! 	      (clobber (match_scratch:SI 5 ""))])]
    "TARGET_80387"
    "
  {
--- 1857,1869 ----
  
  (define_expand "fix_truncxfdi2"
    [(set (match_dup 2)
!       (match_operand:XF 1 "register_operand" ""))
     (parallel [(set (match_operand:DI 0 "general_operand" "")
!                  (fix:DI (fix:XF (match_dup 2))))
!             (clobber (match_dup 2))
!             (clobber (match_dup 3))
!             (clobber (match_dup 4))
!             (clobber (match_scratch:SI 5 ""))])]
    "TARGET_80387"
    "
  {
***************
*** 2134,2156 ****
  
  (define_insn ""
    [(set (match_operand:DI 0 "general_operand" "=rm")
! 	(fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
     (clobber (match_dup 1))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  (define_insn ""
!   [(set (match_operand:DI 0 "general_operand" "=rm")
! 	(fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
     (clobber (match_dup 1))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DI 0 "general_operand" "=rm")
--- 1913,1935 ----
  
  (define_insn ""
    [(set (match_operand:DI 0 "general_operand" "=rm")
!       (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
     (clobber (match_dup 1))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  (define_insn ""
!    [(set (match_operand:DI 0 "general_operand" "=rm")
! 	   (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
     (clobber (match_dup 1))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DI 0 "general_operand" "=rm")
***************
*** 2160,2176 ****
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  ;; Signed MODE_FLOAT conversion to SImode.
  
  (define_expand "fix_truncxfsi2"
    [(parallel [(set (match_operand:SI 0 "general_operand" "")
! 		   (fix:SI
! 		    (fix:XF (match_operand:XF 1 "register_operand" ""))))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387"
    "
  {
--- 1939,1955 ----
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  ;; Signed MODE_FLOAT conversion to SImode.
  
  (define_expand "fix_truncxfsi2"
    [(parallel [(set (match_operand:SI 0 "general_operand" "")
!                  (fix:SI
!                   (fix:XF (match_operand:XF 1 "register_operand" ""))))
!             (clobber (match_dup 2))
!             (clobber (match_dup 3))
!             (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387"
    "
  {
***************
*** 2208,2228 ****
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
! 	(fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
! 	(fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
--- 1987,2007 ----
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
!       (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
!       (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
     (clobber (match_operand:SI 2 "memory_operand" "m"))
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=rm")
***************
*** 2231,2237 ****
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return output_fix_trunc (insn, operands);")
  
  ;; Conversion between fixed point and floating point.
  ;; The actual pattern that matches these is at the end of this file.
--- 2010,2016 ----
     (clobber (match_operand:SI 3 "memory_operand" "m"))
     (clobber (match_scratch:SI 4 "=&q"))]
    "TARGET_80387"
!   "* return (char *) output_fix_trunc (insn, operands);")
  
  ;; Conversion between fixed point and floating point.
  ;; The actual pattern that matches these is at the end of this file.
***************
*** 2264,2276 ****
  
  (define_expand "floatsixf2"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
  (define_expand "floatdixf2"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
--- 2043,2055 ----
  
  (define_expand "floatsixf2"
    [(set (match_operand:XF 0 "register_operand" "")
!       (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
  (define_expand "floatdixf2"
    [(set (match_operand:XF 0 "register_operand" "")
!       (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
***************
*** 2278,2284 ****
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(float:XF (match_operand:DI 1 "general_operand" "rm")))]
    "TARGET_80387"
    "*
  {
--- 2057,2063 ----
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (float:XF (match_operand:DI 1 "general_operand" "rm")))]
    "TARGET_80387"
    "*
  {
***************
*** 2346,2352 ****
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
! 	(float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
    "TARGET_80387"
    "*
  {
--- 2125,2131 ----
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
!       (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))]
    "TARGET_80387"
    "*
  {
***************
*** 2381,2463 ****
  ;;- add instructions
  
  (define_insn "adddi3"
!   [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o")
! 	(plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o")
! 		 (match_operand:DI 2 "general_operand" "o,riF,o,0,0,0,oriF,riF,o,o")))
!    (clobber (match_scratch:SI 3 "=X,X,&r,X,&r,&r,X,&r,&r,&r"))]
    ""
    "*
  {
!   rtx low[3], high[3], xops[7], temp;
  
    CC_STATUS_INIT;
  
-   if (rtx_equal_p (operands[0], operands[2]))
-     {
-       temp = operands[1];
-       operands[1] = operands[2];
-       operands[2] = temp;
-     }
- 
    split_di (operands, 3, low, high);
-   if (!rtx_equal_p (operands[0], operands[1]))
-     {
-       xops[0] = high[0];
-       xops[1] = low[0];
-       xops[2] = high[1];
-       xops[3] = low[1];
- 
-       if (GET_CODE (operands[0]) != MEM)
- 	{
- 	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
- 	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
- 	}
-       else
- 	{
- 	  xops[4] = high[2];
- 	  xops[5] = low[2];
- 	  xops[6] = operands[3];
- 	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
- 	  output_asm_insn (AS2 (add%L6,%5,%6), xops);
- 	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
- 	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
- 	  output_asm_insn (AS2 (adc%L6,%4,%6), xops);
- 	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
- 	  RET;
- 	}
-     }
- 
-   if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG)
-     {
-       xops[0] = high[0];
-       xops[1] = low[0];
-       xops[2] = high[2];
-       xops[3] = low[2];
-       xops[4] = operands[3];
- 
-       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
-       output_asm_insn (AS2 (add%L1,%4,%1), xops);
-       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
-       output_asm_insn (AS2 (adc%L0,%4,%0), xops);
-     }
  
!   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
      {
        output_asm_insn (AS2 (add%L0,%2,%0), low);
        output_asm_insn (AS2 (adc%L0,%2,%0), high);
      }
- 
    else
      output_asm_insn (AS2 (add%L0,%2,%0), high);
- 
    RET;
  }")
  
  ;; On a 486, it is faster to do movl/addl than to do a single leal if
  ;; operands[1] and operands[2] are both registers.
  
  (define_insn "addsi3"
!   [(set (match_operand:SI 0 "general_operand" "=?r,rm,r")
  	(plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  		 (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
    ""
--- 2160,2193 ----
  ;;- add instructions
  
  (define_insn "adddi3"
!   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
! 	(plus:DI (match_operand:DI 1 "general_operand" "%0,0")
! 		 (match_operand:DI 2 "general_operand" "o,riF")))]
    ""
    "*
  {
!   rtx low[3], high[3];
  
    CC_STATUS_INIT;
  
    split_di (operands, 3, low, high);
  
!   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
      {
        output_asm_insn (AS2 (add%L0,%2,%0), low);
        output_asm_insn (AS2 (adc%L0,%2,%0), high);
      }
    else
      output_asm_insn (AS2 (add%L0,%2,%0), high);
    RET;
  }")
  
  ;; On a 486, it is faster to do movl/addl than to do a single leal if
  ;; operands[1] and operands[2] are both registers.
  
+ ; intel1 removed ? from first constraint
  (define_insn "addsi3"
!   [(set (match_operand:SI 0 "general_operand" "=r,rm,r")
  	(plus:SI (match_operand:SI 1 "general_operand" "%r,0,0")
  		 (match_operand:SI 2 "general_operand" "ri,ri,rm")))]
    ""
***************
*** 2468,2487 ****
        if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  	return AS2 (add%L0,%1,%0);
  
!       if (operands[2] == stack_pointer_rtx)
! 	{
! 	  rtx temp;
  
! 	  temp = operands[1];
! 	  operands[1] = operands[2];
! 	  operands[2] = temp;
! 	}
  
!       if (operands[2] != stack_pointer_rtx)
! 	{
! 	  CC_STATUS_INIT;
! 	  operands[1] = SET_SRC (PATTERN (insn));
! 	  return AS2 (lea%L0,%a1,%0);
  	}
  
        output_asm_insn (AS2 (mov%L0,%1,%0), operands);
--- 2198,2220 ----
        if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
  	return AS2 (add%L0,%1,%0);
  
!       if (! (TARGET_486 || TARGET_PENTIUM) || ! REG_P (operands[2]))
!         {
! 	  CC_STATUS_INIT;
  
! 	  if (operands[2] == stack_pointer_rtx)
! 	    {
! 	      rtx temp;
  
! 	      temp = operands[1];
! 	      operands[1] = operands[2];
! 	      operands[2] = temp;
! 	    }
! 	  if (operands[2] != stack_pointer_rtx)
! 	    {
! 	      operands[1] = SET_SRC (PATTERN (insn));
! 	      return AS2 (lea%L0,%a1,%0);
! 	    }
  	}
  
        output_asm_insn (AS2 (mov%L0,%1,%0), operands);
***************
*** 2512,2535 ****
        && GET_CODE (operands[2]) == CONST_INT
        && (INTVAL (operands[2]) & 0xff) == 0)
      {
-       int byteval = (INTVAL (operands[2]) >> 8) & 0xff;
        CC_STATUS_INIT;
  
!       if (byteval == 1)
! 	return AS1 (inc%B0,%h0);
!       else if (byteval == 255)
! 	return AS1 (dec%B0,%h0);
  
-       operands[2] = GEN_INT (byteval);
        return AS2 (add%B0,%2,%h0);
      }
  
    if (operands[2] == const1_rtx)
      return AS1 (inc%W0,%0);
  
!   if (operands[2] == constm1_rtx
!       || (GET_CODE (operands[2]) == CONST_INT
! 	  && INTVAL (operands[2]) == 65535))
      return AS1 (dec%W0,%0);
  
    return AS2 (add%W0,%2,%0);
--- 2245,2267 ----
        && GET_CODE (operands[2]) == CONST_INT
        && (INTVAL (operands[2]) & 0xff) == 0)
      {
        CC_STATUS_INIT;
  
!        operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
! 
!       if (operands[2] == const1_rtx)
!       return AS1 (inc%B0,%h0);
! 
!       if (operands[2] == constm1_rtx)
!       return AS1 (dec%B0,%h0);
  
        return AS2 (add%B0,%2,%h0);
      }
  
    if (operands[2] == const1_rtx)
      return AS1 (inc%W0,%0);
  
!   if (operands[2] == constm1_rtx)
      return AS1 (dec%W0,%0);
  
    return AS2 (add%W0,%2,%0);
***************
*** 2545,2553 ****
    if (operands[2] == const1_rtx)
      return AS1 (inc%B0,%0);
  
!   if (operands[2] == constm1_rtx
!       || (GET_CODE (operands[2]) == CONST_INT
! 	  && INTVAL (operands[2]) == 255))
      return AS1 (dec%B0,%0);
  
    return AS2 (add%B0,%2,%0);
--- 2277,2283 ----
    if (operands[2] == const1_rtx)
      return AS1 (inc%B0,%0);
  
!   if (operands[2] == constm1_rtx)
      return AS1 (dec%B0,%0);
  
    return AS2 (add%B0,%2,%0);
***************
*** 2580,2586 ****
  
  ;; addsi3 is faster, so put this after.
  
! (define_insn "movsi_lea"
    [(set (match_operand:SI 0 "register_operand" "=r")
          (match_operand:QI 1 "address_operand" "p"))]
    ""
--- 2310,2316 ----
  
  ;; addsi3 is faster, so put this after.
  
! (define_insn ""
    [(set (match_operand:SI 0 "register_operand" "=r")
          (match_operand:QI 1 "address_operand" "p"))]
    ""
***************
*** 2610,2617 ****
  
  (define_expand "addxf3"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
! 		 (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
--- 2340,2347 ----
  
  (define_expand "addxf3"
    [(set (match_operand:XF 0 "register_operand" "")
!       (plus:XF (match_operand:XF 1 "nonimmediate_operand" "")
!                (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
***************
*** 2632,2697 ****
  ;;- subtract instructions
  
  (define_insn "subdi3"
!   [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o")
! 	(minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o")
! 		  (match_operand:DI 2 "general_operand" "o,riF,roiF,riF,o")))
!    (clobber (match_scratch:SI 3 "=X,X,X,&r,&r"))]
    ""
    "*
  {
!   rtx low[3], high[3], xops[7];
  
    CC_STATUS_INIT;
  
    split_di (operands, 3, low, high);
  
!   if (!rtx_equal_p (operands[0], operands[1]))
!     {
!       xops[0] = high[0];
!       xops[1] = low[0];
!       xops[2] = high[1];
!       xops[3] = low[1];
! 
!       if (GET_CODE (operands[0]) != MEM)
! 	{
! 	  output_asm_insn (AS2 (mov%L1,%3,%1), xops);
! 	  output_asm_insn (AS2 (mov%L0,%2,%0), xops);
! 	}
!       else
! 	{
! 	  xops[4] = high[2];
! 	  xops[5] = low[2];
! 	  xops[6] = operands[3];
! 	  output_asm_insn (AS2 (mov%L6,%3,%6), xops);
! 	  output_asm_insn (AS2 (sub%L6,%5,%6), xops);
! 	  output_asm_insn (AS2 (mov%L1,%6,%1), xops);
! 	  output_asm_insn (AS2 (mov%L6,%2,%6), xops);
! 	  output_asm_insn (AS2 (sbb%L6,%4,%6), xops);
! 	  output_asm_insn (AS2 (mov%L0,%6,%0), xops);
! 	  RET;
! 	}
!     }
! 
!   if (GET_CODE (operands[3]) == REG)
!     {
!       xops[0] = high[0];
!       xops[1] = low[0];
!       xops[2] = high[2];
!       xops[3] = low[2];
!       xops[4] = operands[3];
! 
!       output_asm_insn (AS2 (mov%L4,%3,%4), xops);
!       output_asm_insn (AS2 (sub%L1,%4,%1), xops);
!       output_asm_insn (AS2 (mov%L4,%2,%4), xops);
!       output_asm_insn (AS2 (sbb%L0,%4,%0), xops);
!     }
! 
!   else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
      {
        output_asm_insn (AS2 (sub%L0,%2,%0), low);
        output_asm_insn (AS2 (sbb%L0,%2,%0), high);
      }
- 
    else
      output_asm_insn (AS2 (sub%L0,%2,%0), high);
  
--- 2362,2384 ----
  ;;- subtract instructions
  
  (define_insn "subdi3"
!   [(set (match_operand:DI 0 "general_operand" "=&r,ro")
! 	(minus:DI (match_operand:DI 1 "general_operand" "0,0")
! 		  (match_operand:DI 2 "general_operand" "o,riF")))]
    ""
    "*
  {
!   rtx low[3], high[3];
  
    CC_STATUS_INIT;
  
    split_di (operands, 3, low, high);
  
!   if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0)
      {
        output_asm_insn (AS2 (sub%L0,%2,%0), low);
        output_asm_insn (AS2 (sbb%L0,%2,%0), high);
      }
    else
      output_asm_insn (AS2 (sub%L0,%2,%0), high);
  
***************
*** 2723,2730 ****
  
  (define_expand "subxf3"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
! 		  (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
--- 2410,2417 ----
  
  (define_expand "subxf3"
    [(set (match_operand:XF 0 "register_operand" "")
!       (minus:XF (match_operand:XF 1 "nonimmediate_operand" "")
!                 (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
***************
*** 2753,2766 ****
  
  (define_insn ""
    [(set (match_operand:HI 0 "general_operand" "=r")
! 	(mult:HI (match_operand:HI 1 "general_operand" "%0")
  		 (match_operand:HI 2 "general_operand" "r")))]
    "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
    "* return AS2 (imul%W0,%2,%0);")
  
  (define_insn "mulhi3"
    [(set (match_operand:HI 0 "general_operand" "=r,r")
! 	(mult:HI (match_operand:HI 1 "general_operand" "%0,rm")
  		 (match_operand:HI 2 "general_operand" "g,i")))]
    ""
    "*
--- 2440,2453 ----
  
  (define_insn ""
    [(set (match_operand:HI 0 "general_operand" "=r")
! 	(mult:SI (match_operand:HI 1 "general_operand" "%0")
  		 (match_operand:HI 2 "general_operand" "r")))]
    "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80"
    "* return AS2 (imul%W0,%2,%0);")
  
  (define_insn "mulhi3"
    [(set (match_operand:HI 0 "general_operand" "=r,r")
! 	(mult:SI (match_operand:HI 1 "general_operand" "%0,rm")
  		 (match_operand:HI 2 "general_operand" "g,i")))]
    ""
    "*
***************
*** 2795,2852 ****
    return AS3 (imul%L0,%2,%1,%0);
  }")
  
! (define_insn "umulqihi3"
    [(set (match_operand:HI 0 "general_operand" "=a")
! 	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
! 		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
    ""
    "mul%B0 %2")
  
- (define_insn "mulqihi3"
-   [(set (match_operand:HI 0 "general_operand" "=a")
- 	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
- 		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
-   ""
-   "imul%B0 %2")
- 
- (define_insn "umulsidi3"
-   [(set (match_operand:DI 0 "register_operand" "=A")
- 	(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
- 		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
-   "TARGET_WIDE_MULTIPLY"
-   "mul%L0 %2")
- 
- (define_insn "mulsidi3"
-   [(set (match_operand:DI 0 "register_operand" "=A")
- 	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
- 		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))]
-   "TARGET_WIDE_MULTIPLY"
-   "imul%L0 %2")
- 
- (define_insn "umulsi3_highpart"
-   [(set (match_operand:SI 0 "register_operand" "=d")
- 	(truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a"))
- 					   (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
- 				  (const_int 32))))
-    (clobber (match_scratch:SI 3 "=a"))]
-   "TARGET_WIDE_MULTIPLY"
-   "mul%L0 %2")
- 
- (define_insn "smulsi3_highpart"
-   [(set (match_operand:SI 0 "register_operand" "=d")
- 	(truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a"))
- 					   (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))
- 				  (const_int 32))))
-    (clobber (match_scratch:SI 3 "=a"))]
-   "TARGET_WIDE_MULTIPLY"
-   "imul%L0 %2")
- 
  ;; The patterns that match these are at the end of this file.
  
  (define_expand "mulxf3"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
! 		 (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
--- 2482,2502 ----
    return AS3 (imul%L0,%2,%1,%0);
  }")
  
! (define_insn ""
    [(set (match_operand:HI 0 "general_operand" "=a")
! 	(mult:SI (zero_extend:HI
! 		  (match_operand:QI 1 "nonimmediate_operand" "%0"))
! 		 (zero_extend:HI
! 		  (match_operand:QI 2 "nonimmediate_operand" "qm"))))]
    ""
    "mul%B0 %2")
  
  ;; The patterns that match these are at the end of this file.
  
  (define_expand "mulxf3"
    [(set (match_operand:XF 0 "register_operand" "")
!       (mult:XF (match_operand:XF 1 "nonimmediate_operand" "")
!                (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
***************
*** 2884,2891 ****
  
  (define_expand "divxf3"
    [(set (match_operand:XF 0 "register_operand" "")
! 	(div:XF (match_operand:XF 1 "nonimmediate_operand" "")
! 		(match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
--- 2534,2541 ----
  
  (define_expand "divxf3"
    [(set (match_operand:XF 0 "register_operand" "")
!       (div:XF (match_operand:XF 1 "nonimmediate_operand" "")
!               (match_operand:XF 2 "nonimmediate_operand" "")))]
    "TARGET_80387"
    "")
  
***************
*** 2990,3009 ****
  ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  
  ;; ??? What if we only change one byte of an offsettable memory reference?
  (define_insn "andsi3"
!   [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
! 	(and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
! 		(match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
    ""
    "*
  {
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
        if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  	  && (! REG_P (operands[1])
  	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
! 	  && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  	{
  	  /* ??? tege: Should forget CC_STATUS only if we clobber a
  	     remembered operand.  Fix that later.  */
--- 2640,2676 ----
  ;; optional reloads to be generated if op 3 is a pseudo in a stack slot.
  
  ;; ??? What if we only change one byte of an offsettable memory reference?
+ ;;(define_insn "andsi3"
+ ;;  [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r")
+ ;;	(and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0")
+ ;;		(match_operand:SI 2 "general_operand" "L,K,ri,rm")))]
+ ;;  ""
+ ;;  "*
+ ;;{
+ ;intel1
  (define_insn "andsi3"
!   [(set (match_operand:SI 0 "general_operand" "=rm,r,r")
! 	(and:SI (match_operand:SI 1 "general_operand" "0,0,rm")
! 		(match_operand:SI 2 "general_operand" "ri,rm,0")))]
    ""
    "*
  {
+   /* intel1 */
+   if (!rtx_equal_p (operands[0], operands[1])
+       && rtx_equal_p (operands[0], operands[2]))
+     {
+       rtx tmp;
+       tmp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = tmp;
+     }
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
        if (INTVAL (operands[2]) == 0xffff && REG_P (operands[0])
  	  && (! REG_P (operands[1])
  	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
! 	  && (! (TARGET_486 || TARGET_PENTIUM) || ! rtx_equal_p (operands[0], operands[1])))
  	{
  	  /* ??? tege: Should forget CC_STATUS only if we clobber a
  	     remembered operand.  Fix that later.  */
***************
*** 3019,3025 ****
  	  && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  	  && (! REG_P (operands[1])
  	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
! 	  && (TARGET_386 || ! rtx_equal_p (operands[0], operands[1])))
  	{
  	  /* ??? tege: Should forget CC_STATUS only if we clobber a
  	     remembered operand.  Fix that later.  */
--- 2686,2692 ----
  	  && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1]))
  	  && (! REG_P (operands[1])
  	      || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0)
! 	  && (! (TARGET_486 || TARGET_PENTIUM) || ! rtx_equal_p (operands[0], operands[1])))
  	{
  	  /* ??? tege: Should forget CC_STATUS only if we clobber a
  	     remembered operand.  Fix that later.  */
***************
*** 3148,3161 ****
  
  ;;- Bit set (inclusive or) instructions
  
  ;; ??? What if we only change one byte of an offsettable memory reference?
  (define_insn "iorsi3"
!   [(set (match_operand:SI 0 "general_operand" "=rm,r")
! 	(ior:SI (match_operand:SI 1 "general_operand" "%0,0")
! 		(match_operand:SI 2 "general_operand" "ri,rm")))]
    ""
    "*
  {
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
--- 2815,2837 ----
  
  ;;- Bit set (inclusive or) instructions
  
+ ;intel1 added last constaints
  ;; ??? What if we only change one byte of an offsettable memory reference?
  (define_insn "iorsi3"
!   [(set (match_operand:SI 0 "general_operand" "=rm,r,r")
! 	(ior:SI (match_operand:SI 1 "general_operand" "%0,0,rm")
! 		(match_operand:SI 2 "general_operand" "ri,rm,0")))]
    ""
    "*
  {
+   /* intel1 */
+   if (!rtx_equal_p (operands[0], operands[1]))
+     {
+       rtx tmp;
+       tmp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = tmp;
+     }
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
***************
*** 3185,3197 ****
    return AS2 (or%L0,%2,%0);
  }")
  
  (define_insn "iorhi3"
!   [(set (match_operand:HI 0 "general_operand" "=rm,r")
! 	(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
! 		(match_operand:HI 2 "general_operand" "ri,rm")))]
    ""
    "*
  {
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
--- 2861,2882 ----
    return AS2 (or%L0,%2,%0);
  }")
  
+ ;intel1 added last constraint
  (define_insn "iorhi3"
!   [(set (match_operand:HI 0 "general_operand" "=rm,r,r")
! 	(ior:HI (match_operand:HI 1 "general_operand" "%0,0,rm")
! 		(match_operand:HI 2 "general_operand" "ri,rm,0")))]
    ""
    "*
  {
+   /* intel1 */
+   if (!rtx_equal_p (operands[0], operands[1]))
+     {
+       rtx tmp;
+       tmp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = tmp;
+     }
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
***************
*** 3227,3238 ****
    return AS2 (or%W0,%2,%0);
  }")
  
  (define_insn "iorqi3"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q")
! 	(ior:QI (match_operand:QI 1 "general_operand" "%0,0")
! 		(match_operand:QI 2 "general_operand" "qn,qmn")))]
    ""
!   "* return AS2 (or%B0,%2,%0);")
  
  ;;- xor instructions
  
--- 2912,2935 ----
    return AS2 (or%W0,%2,%0);
  }")
  
+ ;intel1 added last constraint 
  (define_insn "iorqi3"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q,q")
! 	(ior:QI (match_operand:QI 1 "general_operand" "%0,0,qm")
! 		(match_operand:QI 2 "general_operand" "qn,qmn,0")))]
    ""
!   "* 
! {
!   /* intel1 */
!   if (!rtx_equal_p (operands[0], operands[1]))
!     {
!       rtx tmp;
!       tmp = operands[1];
!       operands[1] = operands[2];
!       operands[2] = tmp;
!     }
!   return AS2 (or%B0,%2,%0);
! }")
  
  ;;- xor instructions
  
***************
*** 3273,3285 ****
    return AS2 (xor%L0,%2,%0);
  }")
  
  (define_insn "xorhi3"
!   [(set (match_operand:HI 0 "general_operand" "=rm,r")
! 	(xor:HI (match_operand:HI 1 "general_operand" "%0,0")
! 		(match_operand:HI 2 "general_operand" "ri,rm")))]
    ""
    "*
  {
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
--- 2970,2991 ----
    return AS2 (xor%L0,%2,%0);
  }")
  
+ ;intel1 added last constraint 
  (define_insn "xorhi3"
!   [(set (match_operand:HI 0 "general_operand" "=rm,r,r")
! 	(xor:HI (match_operand:HI 1 "general_operand" "%0,0,rm")
! 		(match_operand:HI 2 "general_operand" "ri,rm,0")))]
    ""
    "*
  {
+   /* intel1 */
+   if (!rtx_equal_p (operands[0], operands[1]))
+     {
+       rtx tmp;
+       tmp = operands[1];
+       operands[1] = operands[2];
+       operands[2] = tmp;
+     }
    if (GET_CODE (operands[2]) == CONST_INT
        && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])))
      {
***************
*** 3315,3326 ****
    return AS2 (xor%W0,%2,%0);
  }")
  
  (define_insn "xorqi3"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q")
! 	(xor:QI (match_operand:QI 1 "general_operand" "%0,0")
! 		(match_operand:QI 2 "general_operand" "qn,qm")))]
!   ""
!   "* return AS2 (xor%B0,%2,%0);")
  
  ;;- negation instructions
  
--- 3021,3044 ----
    return AS2 (xor%W0,%2,%0);
  }")
  
+ ;intel1 added last constraint 
  (define_insn "xorqi3"
!   [(set (match_operand:QI 0 "general_operand" "=qm,q,q")
! 	(xor:QI (match_operand:QI 1 "general_operand" "%0,0,qm")
! 		(match_operand:QI 2 "general_operand" "qn,qm,0")))]
!   ""
!   "* 
!  {
!   /* intel1 */
!   if (!rtx_equal_p (operands[0], operands[1]))
!     {
!       rtx tmp;
!       tmp = operands[1];
!       operands[1] = operands[2];
!       operands[2] = tmp;
!     }
!  return AS2 (xor%B0,%2,%0);
!  }")
  
  ;;- negation instructions
  
***************
*** 3382,3394 ****
  
  (define_insn "negxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(neg:XF (match_operand:XF 1 "general_operand" "0")))]
    "TARGET_80387"
    "fchs")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
    "TARGET_80387"
    "fchs")
  
--- 3100,3112 ----
  
  (define_insn "negxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (neg:XF (match_operand:XF 1 "general_operand" "0")))]
    "TARGET_80387"
    "fchs")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
    "TARGET_80387"
    "fchs")
  
***************
*** 3398,3530 ****
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(abs:SF (match_operand:SF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs")
  
  (define_insn "absdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
    "TARGET_80387"
!   "fabs")
  
  (define_insn "absxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(abs:XF (match_operand:XF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
    "TARGET_80387"
!   "fabs")
  
  (define_insn "sqrtsf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn "sqrtdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(sqrt:DF (float_extend:DF
  		  (match_operand:SF 1 "general_operand" "0"))))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn "sqrtxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(sqrt:XF (float_extend:XF
! 		  (match_operand:DF 1 "general_operand" "0"))))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
! 	(sqrt:XF (float_extend:XF
! 		  (match_operand:SF 1 "general_operand" "0"))))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsqrt")
  
  (define_insn "sindf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsin")
  
  (define_insn "sinsf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsin")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(float_extend:DF
  		     (match_operand:SF 1 "register_operand" "0"))] 1))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fsin")
  
  (define_insn "sinxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
  	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
    "fsin")
  
  (define_insn "cosdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fcos")
  
  (define_insn "cossf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fcos")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(float_extend:DF
  		     (match_operand:SF 1 "register_operand" "0"))] 2))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
!   "fcos")
  
  (define_insn "cosxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
  	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
!   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
!    && (TARGET_IEEE_FP || flag_fast_math) "
    "fcos")
  
  ;;- one complement instructions
--- 3116,3234 ----
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(abs:SF (match_operand:SF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs"[(set_attr "type" "fpop")])
  
  (define_insn "absdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(abs:DF (match_operand:DF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))]
    "TARGET_80387"
!   "fabs"[(set_attr "type" "fpop")])
  
  (define_insn "absxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (abs:XF (match_operand:XF 1 "general_operand" "0")))]
    "TARGET_80387"
!   "fabs"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))]
    "TARGET_80387"
!   "fabs"[(set_attr "type" "fpop")])
  
  (define_insn "sqrtsf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(sqrt:SF (match_operand:SF 1 "general_operand" "0")))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn "sqrtdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(sqrt:DF (match_operand:DF 1 "general_operand" "0")))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(sqrt:DF (float_extend:DF
  		  (match_operand:SF 1 "general_operand" "0"))))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn "sqrtxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (sqrt:XF (match_operand:XF 1 "general_operand" "0")))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (sqrt:XF (float_extend:XF
!                 (match_operand:DF 1 "general_operand" "0"))))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
!       (sqrt:XF (float_extend:XF
!                 (match_operand:SF 1 "general_operand" "0"))))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsqrt"[(set_attr "type" "fpop")])
  
  (define_insn "sindf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsin"[(set_attr "type" "fpop")])
  
  (define_insn "sinsf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsin"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(float_extend:DF
  		     (match_operand:SF 1 "register_operand" "0"))] 1))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fsin"[(set_attr "type" "fpop")])
  
  (define_insn "sinxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
  	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
    "fsin")
  
  (define_insn "cosdf2"
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fcos"[(set_attr "type" "fpop")])
  
  (define_insn "cossf2"
    [(set (match_operand:SF 0 "register_operand" "=f")
  	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fcos"[(set_attr "type" "fpop")])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
  	(unspec:DF [(float_extend:DF
  		     (match_operand:SF 1 "register_operand" "0"))] 2))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
!   "fcos"[(set_attr "type" "fpop")])
  
  (define_insn "cosxf2"
    [(set (match_operand:XF 0 "register_operand" "=f")
  	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))]
!   "TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math)"
    "fcos")
  
  ;;- one complement instructions
***************
*** 3676,3682 ****
  {
    if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
      {
!       if (!TARGET_386 && INTVAL (operands[2]) == 1)
  	{
  	  output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  	  return AS2 (add%L0,%1,%0);
--- 3380,3386 ----
  {
    if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1]))
      {
!       if ((TARGET_486 || TARGET_PENTIUM) && INTVAL (operands[2]) == 1)
  	{
  	  output_asm_insn (AS2 (mov%L0,%1,%0), operands);
  	  return AS2 (add%L0,%1,%0);
***************
*** 4177,4183 ****
  			 (const_int 1)
  			 (match_operand:SI 2 "general_operand" "r"))
  	(match_operand:SI 3 "const_int_operand" "n"))]
!   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
--- 3881,3887 ----
  			 (const_int 1)
  			 (match_operand:SI 2 "general_operand" "r"))
  	(match_operand:SI 3 "const_int_operand" "n"))]
!   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[2]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
***************
*** 4195,4201 ****
  	(xor:SI (ashift:SI (const_int 1)
  			   (match_operand:SI 1 "general_operand" "r"))
  		(match_operand:SI 2 "general_operand" "0")))]
!   "TARGET_386 && GET_CODE (operands[1]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
--- 3899,3905 ----
  	(xor:SI (ashift:SI (const_int 1)
  			   (match_operand:SI 1 "general_operand" "r"))
  		(match_operand:SI 2 "general_operand" "0")))]
!   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[1]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
***************
*** 4208,4214 ****
  	(xor:SI (match_operand:SI 1 "general_operand" "0")
  		(ashift:SI (const_int 1)
  			   (match_operand:SI 2 "general_operand" "r"))))]
!   "TARGET_386 && GET_CODE (operands[2]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
--- 3912,3918 ----
  	(xor:SI (match_operand:SI 1 "general_operand" "0")
  		(ashift:SI (const_int 1)
  			   (match_operand:SI 2 "general_operand" "r"))))]
!   "! (TARGET_486 || TARGET_PENTIUM) && GET_CODE (operands[2]) != CONST_INT"
    "*
  {
    CC_STATUS_INIT;
***************
*** 4553,4558 ****
--- 4257,4271 ----
    if (cc_prev_status.flags & CC_Z_IN_NOT_C)
      return \"jnc %l0\";
    else
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4000);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (jne,%l0);
+     }
+ 
      return \"je %l0\";
  }")
  
***************
*** 4585,4590 ****
--- 4298,4312 ----
    if (cc_prev_status.flags & CC_Z_IN_NOT_C)
      return \"jc %l0\";
    else
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4000);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (je,%l0);
+     }
+ 
      return \"jne %l0\";
  }")
  
***************
*** 4610,4615 ****
--- 4332,4344 ----
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (je,%l0);
  
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4100);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (je,%l0);
+     }
    OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  }")
  
***************
*** 4654,4659 ****
--- 4383,4396 ----
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (je,%l0);
  
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x100);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (jne,%l0);
+     }
    OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  }")
  
***************
*** 4697,4703 ****
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (je,%l0);
! 
    OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  }")
  
--- 4434,4447 ----
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (je,%l0);
!   /* intel1 */
!   if (cc_prev_status.flags & CC_TEST_AX)
!     {
!       operands[1] = gen_rtx (REG, SImode, 0);
!       operands[2] = GEN_INT (0x100);
!       output_asm_insn (AS2 (testl,%2,%1), operands);
!       return AS1 (je,%l0);
!     }
    OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  }")
  
***************
*** 4741,4746 ****
--- 4485,4498 ----
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jb,%l0);
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4100);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (jne,%l0);
+     }
  
    OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  }")
***************
*** 4778,4783 ****
--- 4530,4543 ----
    if (cc_prev_status.flags & CC_Z_IN_NOT_C)
      return \"jc %l0\";
    else
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4000);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (je,%l0);
+     }
      return \"jne %l0\";
  }")
  
***************
*** 4793,4798 ****
--- 4553,4566 ----
    if (cc_prev_status.flags & CC_Z_IN_NOT_C)
      return \"jnc %l0\";
    else
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4000);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (jne,%l0);
+     }
      return \"je %l0\";
  }")
  
***************
*** 4807,4813 ****
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jne,%l0);
! 
    OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  }")
  
--- 4575,4588 ----
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jne,%l0);
!   /* intel1 */
!   if (cc_prev_status.flags & CC_TEST_AX)
!     {
!       operands[1] = gen_rtx (REG, SImode, 0);
!       operands[2] = GEN_INT (0x4100);
!       output_asm_insn (AS2 (testl,%2,%1), operands);
!       return AS1 (jne,%l0);
!     }
    OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR);
  }")
  
***************
*** 4831,4836 ****
--- 4606,4619 ----
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jne,%l0);
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x100);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (je,%l0);
+     }
  
    OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\");
  }")
***************
*** 4855,4861 ****
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jne,%l0);
! 
    OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  }")
  
--- 4638,4651 ----
  {
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jne,%l0);
!   /* intel1 */
!   if (cc_prev_status.flags & CC_TEST_AX)
!     {
!       operands[1] = gen_rtx (REG, SImode, 0);
!       operands[2] = GEN_INT (0x100);
!       output_asm_insn (AS2 (testl,%2,%1), operands);
!       return AS1 (jne,%l0);
!     }
    OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\");
  }")
  
***************
*** 4880,4885 ****
--- 4670,4683 ----
    if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387))
      return AS1 (jae,%l0);
  
+   /* intel1 */
+   if (cc_prev_status.flags & CC_TEST_AX)
+     {
+       operands[1] = gen_rtx (REG, SImode, 0);
+       operands[2] = GEN_INT (0x4100);
+       output_asm_insn (AS2 (testl,%2,%1), operands);
+       return AS1 (je,%l0);
+     }
    OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR);
  }")
  
***************
*** 5296,5346 ****
    "!HALF_PIC_P ()"
    "call %P1")
  
- ;; Call subroutine returning any type.
- 
  (define_expand "untyped_call"
!   [(parallel [(call (match_operand 0 "" "")
  		    (const_int 0))
! 	      (match_operand 1 "" "")
  	      (match_operand 2 "" "")])]
    ""
    "
  {
!   int i;
  
!   /* In order to give reg-stack an easier job in validating two
!      coprocessor registers as containing a possible return value,
!      simply pretend the untyped call returns a complex long double
!      value.  */
!   emit_call_insn (TARGET_80387
!                   ? gen_call_value (gen_rtx (REG, XCmode, FIRST_FLOAT_REG),
! 		                  operands[0], const0_rtx)
!                   : gen_call (operands[0], const0_rtx));
! 
!   for (i = 0; i < XVECLEN (operands[2], 0); i++)
!     {
!       rtx set = XVECEXP (operands[2], 0, i);
!       emit_move_insn (SET_DEST (set), SET_SRC (set));
!     }
! 
!   /* The optimizer does not know that the call sets the function value
!      registers we stored in the result block.  We avoid problems by
!      claiming that all hard registers are used and clobbered at this
!      point.  */
!   emit_insn (gen_blockage ());
  
!   DONE;
! }")
  
! ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
! ;; all of memory.  This blocks insns from being moved across this point.
  
! (define_insn "blockage"
!   [(unspec_volatile [(const_int 0)] 0)]
    ""
!   "")
  
! ;; Insn emitted into the body of a function to return from a function.
  ;; This is only done if the function's epilogue is known to be simple.
  ;; See comments for simple_386_epilogue in i386.c.
  
--- 5094,5221 ----
    "!HALF_PIC_P ()"
    "call %P1")
  
  (define_expand "untyped_call"
!   [(parallel [(call (match_operand:QI 0 "indirect_operand" "")
  		    (const_int 0))
! 	      (match_operand:BLK 1 "memory_operand" "")
  	      (match_operand 2 "" "")])]
    ""
    "
  {
!   rtx addr;
  
!   if (flag_pic)
!     current_function_uses_pic_offset_table = 1;
  
!   /* With half-pic, force the address into a register.  */
!   addr = XEXP (operands[0], 0);
!   if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr))
!     XEXP (operands[0], 0) = force_reg (Pmode, addr);
  
!   operands[1] = change_address (operands[1], DImode, XEXP (operands[1], 0));
!   if (! expander_call_insn_operand (operands[1], QImode))
!     operands[1]
!       = change_address (operands[1], VOIDmode,
! 			copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
! }")
  
! (define_insn ""
!   [(call (match_operand:QI 0 "call_insn_operand" "m")
! 	 (const_int 0))
!    (match_operand:DI 1 "memory_operand" "o")
!    (match_operand 2 "" "")]
    ""
!   "*
! {
!   rtx addr = operands[1];
  
!   if (GET_CODE (operands[0]) == MEM
!       && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0)))
!     {
!       operands[0] = XEXP (operands[0], 0);
!       output_asm_insn (AS1 (call,%*%0), operands);
!     }
!   else
!     output_asm_insn (AS1 (call,%P0), operands);
! 
!   operands[2] = gen_rtx (REG, SImode, 0);
!   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
! 
!   operands[2] = gen_rtx (REG, SImode, 1);
!   operands[1] = adj_offsettable_operand (addr, 4);
!   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
! 
!   operands[1] = adj_offsettable_operand (addr, 8);
!   return AS1 (fnsave,%1);
! }")
! 
! (define_insn ""
!   [(call (mem:QI (match_operand:SI 0 "symbolic_operand" ""))
! 	 (const_int 0))
!    (match_operand:DI 1 "memory_operand" "o")
!    (match_operand 2 "" "")]
!   "!HALF_PIC_P ()"
!   "*
! {
!   rtx addr = operands[1];
! 
!   output_asm_insn (AS1 (call,%P0), operands);
! 
!   operands[2] = gen_rtx (REG, SImode, 0);
!   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
! 
!   operands[2] = gen_rtx (REG, SImode, 1);
!   operands[1] = adj_offsettable_operand (addr, 4);
!   output_asm_insn (AS2 (mov%L2,%2,%1), operands);
! 
!   operands[1] = adj_offsettable_operand (addr, 8);
!   return AS1 (fnsave,%1);
! }")
! 
! ;; We use fnsave and frstor to save and restore the floating point result.
! ;; These are expensive instructions and require a large space to save the
! ;; FPU state.  An more complicated alternative is to use fnstenv to store
! ;; the FPU environment and test whether the stack top is valid.  Store the
! ;; result of the test, and if it is valid, pop and save the value.  The
! ;; untyped_return would check the test and optionally push the saved value.
! 
! (define_expand "untyped_return"
!   [(match_operand:BLK 0 "memory_operand" "")
!    (match_operand 1 "" "")]
!   ""
!   "
! {
!   rtx valreg1 = gen_rtx (REG, SImode, 0);
!   rtx valreg2 = gen_rtx (REG, SImode, 1);
!   rtx result = operands[0];
! 
!   /* Restore the FPU state.  */
!   emit_insn (gen_update_return (change_address (result, SImode,
! 						plus_constant (XEXP (result, 0),
! 							       8))));
! 
!   /* Reload the function value registers.  */
!   emit_move_insn (valreg1, change_address (result, SImode, XEXP (result, 0)));
!   emit_move_insn (valreg2,
! 		  change_address (result, SImode,
! 				  plus_constant (XEXP (result, 0), 4)));
! 
!   /* Put USE insns before the return.  */
!   emit_insn (gen_rtx (USE, VOIDmode, valreg1));
!   emit_insn (gen_rtx (USE, VOIDmode, valreg2));
! 
!   /* Construct the return.  */
!   expand_null_return ();
! 
!   DONE;
! }")
! 
! (define_insn "update_return"
!   [(unspec:SI [(match_operand:SI 0 "memory_operand" "m")] 0)]
!   ""
!   "frstor %0")
! 
! ;; Insn emitted into the body of a function to return from a function.
  ;; This is only done if the function's epilogue is known to be simple.
  ;; See comments for simple_386_epilogue in i386.c.
  
***************
*** 5387,5393 ****
  ;; It might seem that operands 0 & 1 could use predicate register_operand.
  ;; But strength reduction might offset the MEM expression.  So we let
  ;; reload put the address into %edi & %esi.
! 
  (define_insn ""
    [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  	(mem:BLK (match_operand:SI 1 "address_operand" "S")))
--- 5262,5268 ----
  ;; It might seem that operands 0 & 1 could use predicate register_operand.
  ;; But strength reduction might offset the MEM expression.  So we let
  ;; reload put the address into %edi & %esi.
! ;; intel1 "e" used to be "S"
  (define_insn ""
    [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
  	(mem:BLK (match_operand:SI 1 "address_operand" "S")))
***************
*** 5463,5468 ****
--- 5338,5344 ----
  ;; possible to know that the length is non-zero, and to avoid the extra
  ;; code to handle zero-length compares.
  
+ ;; intel1 "e" used to be "S"
  (define_insn ""
    [(set (match_operand:SI 0 "general_operand" "=&r")
  	(compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S"))
***************
*** 5499,5504 ****
--- 5375,5381 ----
    RET;
  }")
  
+ ;; intel1 "e" used to be "S"
  (define_insn ""
    [(set (cc0)
  	(compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
***************
*** 5553,5571 ****
    output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"jnz %sLFFSSI%d\",
! 	   LOCAL_LABEL_PREFIX, ffssi_label_number);
  #else
    sprintf (buffer, \"jnz %sLFFSSI%d\",
! 	   \"\", ffssi_label_number);
  #endif
    output_asm_insn (buffer, xops);
    output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"%sLFFSSI%d:\",
! 	   LOCAL_LABEL_PREFIX, ffssi_label_number);
  #else
    sprintf (buffer, \"%sLFFSSI%d:\",
! 	   \"\", ffssi_label_number);
  #endif
    output_asm_insn (buffer, xops);
  
--- 5430,5448 ----
    output_asm_insn (AS2 (bsf%L0,%1,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"jnz %sLFFSSI%d\",
!          LOCAL_LABEL_PREFIX, ffssi_label_number);
  #else
    sprintf (buffer, \"jnz %sLFFSSI%d\",
!          \"\", ffssi_label_number);
  #endif
    output_asm_insn (buffer, xops);
    output_asm_insn (AS2 (mov%L0,%2,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"%sLFFSSI%d:\",
!          LOCAL_LABEL_PREFIX, ffssi_label_number);
  #else
    sprintf (buffer, \"%sLFFSSI%d:\",
!          \"\", ffssi_label_number);
  #endif
    output_asm_insn (buffer, xops);
  
***************
*** 5599,5617 ****
    output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"jnz %sLFFSHI%d\",
! 	   LOCAL_LABEL_PREFIX, ffshi_label_number);
  #else
    sprintf (buffer, \"jnz %sLFFSHI%d\",
! 	   \"\", ffshi_label_number);
  #endif
    output_asm_insn (buffer, xops);
    output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"%sLFFSHI%d:\",
! 	   LOCAL_LABEL_PREFIX, ffshi_label_number);
  #else
    sprintf (buffer, \"%sLFFSHI%d:\",
! 	   \"\", ffshi_label_number);
  #endif
    output_asm_insn (buffer, xops);
  
--- 5476,5494 ----
    output_asm_insn (AS2 (bsf%W0,%1,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"jnz %sLFFSHI%d\",
!          LOCAL_LABEL_PREFIX, ffshi_label_number);
  #else
    sprintf (buffer, \"jnz %sLFFSHI%d\",
!          \"\", ffshi_label_number);
  #endif
    output_asm_insn (buffer, xops);
    output_asm_insn (AS2 (mov%W0,%2,%0), xops);
  #ifdef LOCAL_LABEL_PREFIX
    sprintf (buffer, \"%sLFFSHI%d:\",
!          LOCAL_LABEL_PREFIX, ffshi_label_number);
  #else
    sprintf (buffer, \"%sLFFSHI%d:\",
!          \"\", ffshi_label_number);
  #endif
    output_asm_insn (buffer, xops);
  
***************
*** 5626,5639 ****
  ;; the other operand a conversion.  The conversion may be SFmode or
  ;; SImode if the target mode DFmode, but only SImode if the target mode
  ;; is SFmode.
! 
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
  	(match_operator:DF 3 "binary_387_op"
  			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
! 			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
--- 5503,5525 ----
  ;; the other operand a conversion.  The conversion may be SFmode or
  ;; SImode if the target mode DFmode, but only SImode if the target mode
  ;; is SFmode.
! ;; intel1 2 changed from nonimmediate operand to general operand
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
  	(match_operator:DF 3 "binary_387_op"
  			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
! 			 (match_operand:DF 2 "general_operand" "fm,0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
***************
*** 5641,5647 ****
  	   [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  	    (match_operand:DF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
--- 5527,5533 ----
  	   [(float:DF (match_operand:SI 1 "general_operand" "rm"))
  	    (match_operand:DF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
***************
*** 5649,5655 ****
  			[(match_operand:XF 1 "nonimmediate_operand" "0,f")
  			 (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
--- 5535,5541 ----
  			[(match_operand:XF 1 "nonimmediate_operand" "0,f")
  			 (match_operand:XF 2 "nonimmediate_operand" "f,0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
***************
*** 5657,5663 ****
  	   [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  	    (match_operand:XF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
--- 5543,5549 ----
  	   [(float:XF (match_operand:SI 1 "general_operand" "rm"))
  	    (match_operand:XF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
***************
*** 5665,5671 ****
  	   [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  	    (match_operand:XF 2 "general_operand" "0,f")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
--- 5551,5557 ----
  	   [(float_extend:XF (match_operand:SF 1 "general_operand" "fm,0"))
  	    (match_operand:XF 2 "general_operand" "0,f")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f")
***************
*** 5673,5679 ****
  	  [(match_operand:XF 1 "general_operand" "0")
  	   (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
--- 5559,5565 ----
  	  [(match_operand:XF 1 "general_operand" "0")
  	   (float:XF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:XF 0 "register_operand" "=f,f")
***************
*** 5681,5688 ****
  	  [(match_operand:XF 1 "general_operand" "0,f")
  	   (float_extend:XF
  	    (match_operand:SF 2 "general_operand" "fm,0"))]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
--- 5567,5584 ----
  	  [(match_operand:XF 1 "general_operand" "0,f")
  	   (float_extend:XF
  	    (match_operand:SF 2 "general_operand" "fm,0"))]))]
+ 
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
***************
*** 5690,5696 ****
  	   [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  	    (match_operand:DF 2 "general_operand" "0,f")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
--- 5586,5601 ----
  	   [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0"))
  	    (match_operand:DF 2 "general_operand" "0,f")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f")
***************
*** 5698,5704 ****
  	  [(match_operand:DF 1 "general_operand" "0")
  	   (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
--- 5603,5618 ----
  	  [(match_operand:DF 1 "general_operand" "0")
  	   (float:DF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:DF 0 "register_operand" "=f,f")
***************
*** 5707,5721 ****
  	   (float_extend:DF
  	    (match_operand:SF 2 "general_operand" "fm,0"))]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f,f")
  	(match_operator:SF 3 "binary_387_op"
! 			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
! 			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
--- 5621,5654 ----
  	   (float_extend:DF
  	    (match_operand:SF 2 "general_operand" "fm,0"))]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
+ ;; intel1 1 and 2 changed from nonimmediate operand to general operand
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f,f")
  	(match_operator:SF 3 "binary_387_op"
! 			[(match_operand:SF 1 "general_operand" "0,fm")
! 			 (match_operand:SF 2 "general_operand" "fm,0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
***************
*** 5723,5729 ****
  	  [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  	   (match_operand:SF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
--- 5656,5671 ----
  	  [(float:SF (match_operand:SI 1 "general_operand" "rm"))
  	   (match_operand:SF 2 "general_operand" "0")]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_insn ""
    [(set (match_operand:SF 0 "register_operand" "=f")
***************
*** 5731,5737 ****
  	  [(match_operand:SF 1 "general_operand" "0")
  	   (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return output_387_binary_op (insn, operands);")
  
  (define_expand "strlensi"
    [(parallel [(set (match_dup 4)
--- 5673,5688 ----
  	  [(match_operand:SF 1 "general_operand" "0")
  	   (float:SF (match_operand:SI 2 "general_operand" "rm"))]))]
    "TARGET_80387"
!   "* return (char *) output_387_binary_op (insn, operands);"
!   [(set (attr "type") 
!         (cond [(match_operand:DF 3 "is_mul" "") 
!                  (const_string "fpop")
!                (match_operand:DF 3 "is_div" "") 
!                  (const_string "fpdiv")
!               ]
!                (const_string "fpop")
!         )
!   )])
  
  (define_expand "strlensi"
    [(parallel [(set (match_dup 4)
***************
*** 5773,5775 ****
--- 5724,6535 ----
    output_asm_insn (AS2 (mov%L0,%1,%0), xops);
    return \"repnz\;scas%B2\";
  }")
+ 
+ ;; intel1 peepholes
+ ;; change fstp mem1
+ ;;        fld  mem1
+ ;;        fop  mem2
+ ;; to
+ ;;        fst  mem1
+ ;;        fop  mem2
+ 
+ (define_peephole
+  [(set (match_operand:DF 0 "memory_operand" "g")
+        (reg:DF 8))
+   (set (reg:DF 8)
+        (match_operand:DF 1 "memory_operand" "g"))
+   (set (reg:DF 8)
+ 	(mult:DF (reg:DF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstpl,%0),operands);
+           output_asm_insn (AS1 (fldl,%1),operands);
+           return AS1(fmull,%0);
+         }
+       output_asm_insn (AS1 (fstl,%0),operands);
+       return AS1(fmull,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fstl,%0),operands);
+       output_asm_insn (AS1 (fldl,%1),operands);
+       return AS1(fmull,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:DF 0 "memory_operand" "g")
+        (reg:DF 8))
+   (set (reg:DF 8)
+        (match_operand:DF 1 "memory_operand" "g"))
+   (set (reg:DF 8)
+ 	(plus:DF (reg:DF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstpl,%0),operands);
+           output_asm_insn (AS1 (fldl,%1),operands);
+           return AS1(faddl,%0);
+         }
+       output_asm_insn (AS1 (fstl,%0),operands);
+       return AS1(faddl,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fstl,%0),operands);
+       output_asm_insn (AS1 (fldl,%1),operands);
+       return AS1(faddl,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:DF 0 "memory_operand" "g")
+        (reg:DF 8))
+   (set (reg:DF 8)
+        (match_operand:DF 1 "memory_operand" "g"))
+   (set (reg:DF 8)
+ 	(minus:DF (reg:DF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstpl,%0),operands);
+           output_asm_insn (AS1 (fldl,%1),operands);
+           return AS1(fsubl,%0);
+         }
+       output_asm_insn (AS1 (fstl,%0),operands);
+       return AS1(fsubrl,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fstl,%0),operands);
+       output_asm_insn (AS1 (fldl,%1),operands);
+       return AS1(fsubl,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:DF 0 "memory_operand" "g")
+        (reg:DF 8))
+   (set (reg:DF 8)
+        (match_operand:DF 1 "memory_operand" "g"))
+   (set (reg:DF 8)
+ 	(div:DF (reg:DF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstpl,%0),operands);
+           output_asm_insn (AS1 (fldl,%1),operands);
+           return AS1(fdivl,%0);
+         }
+       output_asm_insn (AS1 (fstl,%0),operands);
+       return AS1(fdivrl,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fstl,%0),operands);
+       output_asm_insn (AS1 (fldl,%1),operands);
+       return AS1(fdivl,%0);
+     }
+  }"
+ );
+  
+  
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:SF 8)
+        (match_operand:SF 1 "memory_operand" "g"))
+   (set (reg:SF 8)
+ 	(mult:SF (reg:SF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstps,%0),operands);
+           output_asm_insn (AS1 (flds,%1),operands);
+           return AS1(fmuls,%0);
+         }
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1(fmuls,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       output_asm_insn (AS1 (flds,%1),operands);
+       return AS1(fmuls,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:SF 8)
+        (match_operand:SF 1 "memory_operand" "g"))
+   (set (reg:SF 8)
+ 	(plus:SF (reg:SF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstps,%0),operands);
+           output_asm_insn (AS1 (flds,%1),operands);
+           return AS1(fadds,%0);
+         }
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1(fadds,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       output_asm_insn (AS1 (flds,%1),operands);
+       return AS1(fadds,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:SF 8)
+        (match_operand:SF 1 "memory_operand" "g"))
+   (set (reg:SF 8)
+ 	(minus:SF (reg:SF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstps,%0),operands);
+           output_asm_insn (AS1 (flds,%1),operands);
+           return AS1(fsubs,%0);
+         }
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1(fsubrs,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       output_asm_insn (AS1 (flds,%1),operands);
+       return AS1(fsubs,%0);
+     }
+  }"
+ );
+  
+  
+  
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:SF 8)
+        (match_operand:SF 1 "memory_operand" "g"))
+   (set (reg:SF 8)
+ 	(div:SF (reg:SF 8)
+ 		 (match_dup 0)))
+  ]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if (flag_float_store)
+         {
+           output_asm_insn (AS1 (fstps,%0),operands);
+           output_asm_insn (AS1 (flds,%1),operands);
+           return AS1(fdivs,%0);
+         }
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1(fdivrs,%1);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       output_asm_insn (AS1 (flds,%1),operands);
+       return AS1(fdivs,%0);
+     }
+  }"
+ );
+  
+  
+ ;; change fstp mem1
+ ;;        fld  mem1
+ ;; to
+ ;;        fst  mem1
+  
+ (define_peephole
+  [(set (match_operand:DF 0 "memory_operand" "g")
+        (reg:DF 8))
+   (set (reg:DF 8)
+        (match_dup 0))]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if(!MEM_VOLATILE_P (operands[0]) && !flag_float_store)
+         {
+           return AS1 (fstl,%0);
+         }
+       else
+         {
+          output_asm_insn (AS1 (fstpl,%0),operands);
+          return AS1 (fldl,%0);
+         }
+     }
+   else
+     {
+       output_asm_insn (AS1 (fstl,%0),operands);
+       return AS1 (fldl,%0);
+     }
+  }"
+ );
+ 
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:SF 8)
+        (match_dup 0))]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG))
+     {
+       if(!MEM_VOLATILE_P (operands[0]) && !flag_float_store)
+         {
+           return AS1 (fsts,%0);
+         }
+       else
+         {
+          output_asm_insn (AS1 (fstps,%0),operands);
+          return AS1 (flds,%0);
+         }
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1 (flds,%0);
+     }
+  }"
+ );
+ 
+ (define_peephole
+  [(set (match_operand:SF 0 "memory_operand" "g")
+        (reg:SF 8))
+   (set (reg:DF 8)
+        (float_extend:DF (match_dup 0)))]
+  "TARGET_80387"
+  "*
+  {
+   extern int flag_float_store;
+   if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) && !flag_float_store)
+     {
+       return AS1 (fsts,%0);
+     }
+   else
+     {
+       output_asm_insn (AS1 (fsts,%0),operands);
+       return AS1 (flds,%0);
+     }
+  }"
+ );
+ 
+ ;; see if compare can be deleted
+ (define_peephole
+   [
+    (set (cc0)
+ 	(compare (const_int 0)
+ 		 (match_operand:SI 0 "general_operand" "g")))
+    (set (pc)
+ 	(if_then_else (ne (cc0)
+ 			  (const_int 0))
+ 			  (label_ref (match_operand 1 "" ""))
+ 		      (pc)))
+   ]
+   ""
+   "*
+ {
+       if(!last_to_set_cc(operands[0]),insn)
+       {
+         operands[2] = const0_rtx;
+         output_asm_insn (AS2 (cmp%L0,%2,%0),operands);
+         return \"jne %l1\";
+       }
+       else
+       {
+         return \"jne %l1\";
+       }
+ }");
+   
+ (define_peephole
+   [
+    (set (cc0)
+ 	(compare (match_operand:SI 0 "general_operand" "g")
+ 		 (const_int 0)))
+    (set (pc)
+ 	(if_then_else (ne (cc0)
+ 			  (const_int 0))
+ 			  (label_ref (match_operand 1 "" ""))
+ 		      (pc)))
+   ]
+   ""
+   "*
+ {
+       if(!last_to_set_cc(operands[0],insn))
+       {
+         operands[2] = const0_rtx;
+         output_asm_insn (AS2 (cmp%L0,%2,%0),operands);
+         return \"jne %l1\";
+       }
+       else
+       {
+         return \"jne %l1\";
+       }
+ }");
+ 
+ ;; optimization of sign_extend combined with and
+ (define_peephole
+   [
+    (set (match_operand:HI 0 "register_operand" "")
+ 	(and:HI (match_dup 0)
+ 		(match_operand:HI 1 "immediate_operand" "")))
+    (set (match_operand:SI 2 "register_operand" "")
+ 	(sign_extend:SI
+ 	 (match_dup 0)))
+   ]
+   ""
+   "*
+ {
+       int no_sign_extend = 0;
+       rtx note;
+       if ((INTVAL (operands[1]) & 0x8000) == 0)
+         { /* Don't need to do sign extend */
+           no_sign_extend = 1;
+         }
+       CC_STATUS_INIT;
+       if (no_sign_extend)
+         {
+ 	  if (REGNO (operands[0]) == REGNO (operands[2]))
+ 	    {
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (and%L0,%1,%0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      output_asm_insn (AS2 (and%W0,%1,%w0), operands);
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (mov%L0,%0,%2), operands);
+ 	      operands [1] = gen_rtx (CONST_INT, 0, 0xffff);
+ 	      output_asm_insn (AS2 (and%L0,%1,%2), operands);
+ 	    }
+ 	  RET;
+         }
+       /* Can we ignore the upper byte? */
+       else if (QI_REG_P (operands[0])
+ 	  && (INTVAL (operands[1]) & 0xff00) == 0xff00)
+ 	{
+ 	  if ((INTVAL (operands[1]) & 0xff) == 0)
+ 	    {
+ 	      operands[1] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%1,%b0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
+ 	      output_asm_insn (AS2 (and%B0,%1,%b0), operands);
+ 	    }
+ 	}
+       else if (!no_sign_extend && QI_REG_P (operands[0]) 
+                && (INTVAL (operands[1]) & 0xff) == 0xff)
+ 	{
+ 	  if ((INTVAL (operands[1]) & 0xff00) == 0)
+ 	    {
+ 	      operands[1] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%1,%h0), operands);
+ 	    }
+ 
+ 	  operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff);
+ 	  output_asm_insn (AS2 (and%B0,%1,%b0), operands);
+ 	}
+   if (REGNO (operands[2]) == 0 && REGNO (operands[0]) == 0)
+ #ifdef INTEL_SYNTAX
+     return \"cwde\";
+ #else
+     return \"cwtl\";
+ #endif
+ 
+ #ifdef INTEL_SYNTAX
+   return AS2 (movsx,%0,%2);
+ #else
+   return AS2 (movs%W0%L0,%0,%2);
+ #endif
+ }");
+ 
+ (define_peephole
+   [
+    (set (match_operand:HI 0 "register_operand" "")
+ 	(match_operand:HI 1 "memory_operand" ""))
+    (set (match_dup 0)
+ 	(and:HI (match_dup 0)
+ 		(match_operand:HI 2 "immediate_operand" "")))
+    (set (match_operand:SI 3 "register_operand" "")
+ 	(sign_extend:SI
+ 	 (match_dup 0)))
+   ]
+   ""
+   "*
+ {
+       int no_sign_extend = 0;
+       if ((INTVAL (operands[2]) & 0xff00) == 0
+           && QI_REG_P (operands[0]))
+         {
+           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
+         }
+       else
+         {
+           output_asm_insn (AS2 (mov%W0,%1,%0), operands);
+         }
+       if ((INTVAL (operands[2]) & 0x8000) == 0)
+         { /* Don't need to do sign extend */
+           no_sign_extend = 1;
+         }
+       CC_STATUS_INIT;
+       if (no_sign_extend)
+         {
+ 	  if (REGNO (operands[0]) == REGNO (operands[3]))
+ 	    {
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (and%L0,%2,%0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      output_asm_insn (AS2 (and%W0,%2,%w0), operands);
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (mov%L0,%0,%3), operands);
+ 	      operands [2] = gen_rtx (CONST_INT, 0, 0xffff);
+ 	      output_asm_insn (AS2 (and%L0,%2,%3), operands);
+ 	    }
+ 	  RET;
+         }
+       /* Can we ignore the upper byte? */
+       else if (QI_REG_P (operands[0])
+ 	  && (INTVAL (operands[2]) & 0xff00) == 0xff00)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
+ 	      output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	    }
+ 	}
+       else if (!no_sign_extend && QI_REG_P (operands[0]) 
+                && (INTVAL (operands[2]) & 0xff) == 0xff)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff00) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
+ 	    }
+ 
+ 	  operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
+ 	  output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	}
+       else
+         {
+           output_asm_insn (AS2 (and%W0,%2,%0), operands);
+         }
+   if (REGNO (operands[3]) == 0 && REGNO (operands[0]) == 0)
+ #ifdef INTEL_SYNTAX
+     return \"cwde\";
+ #else
+     return \"cwtl\";
+ #endif
+ 
+ #ifdef INTEL_SYNTAX
+   return AS2 (movsx,%0,%3);
+ #else
+   return AS2 (movs%W0%L0,%0,%3);
+ #endif
+ }");
+ 
+ (define_peephole
+   [
+    (set (match_operand:HI 0 "register_operand" "")
+ 	(sign_extend:HI
+ 	 (match_operand:QI 1 "memory_operand" "")))
+    (set (match_dup 0)
+ 	(and:HI (match_dup 0)
+ 		(match_operand:HI 2 "immediate_operand" "")))
+    (set (match_operand:SI 3 "register_operand" "")
+ 	(sign_extend:SI
+ 	 (match_dup 0)))
+   ]
+   ""
+   "*
+ {
+       int no_sign_extend = 0;
+       if ((INTVAL (operands[2]) & 0xff00) == 0
+           && QI_REG_P (operands[0]))
+         {
+           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
+         }
+       else
+         {
+ #ifdef INTEL_SYNTAX
+           output_asm_insn( AS2 (movsx,%1,%0), operands);
+ #else
+           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
+ #endif
+         }
+       if ((INTVAL (operands[2]) & 0x8000) == 0)
+         { /* Don't need to do sign extend */
+           no_sign_extend = 1;
+         }
+       CC_STATUS_INIT;
+       if (no_sign_extend)
+         {
+ 	  if (REGNO (operands[0]) == REGNO (operands[3]))
+ 	    {
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (and%L0,%2,%0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      output_asm_insn (AS2 (and%W0,%2,%w0), operands);
+               operands [0] = gen_rtx (REG, SImode, REGNO (operands[0]));
+ 	      output_asm_insn (AS2 (mov%L0,%0,%3), operands);
+ 	      operands [2] = gen_rtx (CONST_INT, 0, 0xffff);
+ 	      output_asm_insn (AS2 (and%L0,%2,%3), operands);
+ 	    }
+ 	  RET;
+         }
+       /* Can we ignore the upper byte? */
+       else if (QI_REG_P (operands[0])
+ 	  && (INTVAL (operands[2]) & 0xff00) == 0xff00)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
+ 	      output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	    }
+ 	}
+       else if (!no_sign_extend && QI_REG_P (operands[0]) 
+                && (INTVAL (operands[2]) & 0xff) == 0xff)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff00) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
+ 	    }
+ 
+ 	  operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
+ 	  output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	}
+       else
+         {
+           output_asm_insn (AS2 (and%W0,%2,%0), operands);
+         }
+   if (REGNO (operands[3]) == 0 && REGNO (operands[0]) == 0)
+ #ifdef INTEL_SYNTAX
+     return \"cwde\";
+ #else
+     return \"cwtl\";
+ #endif
+ 
+ #ifdef INTEL_SYNTAX
+   return AS2 (movsx,%0,%3);
+ #else
+   return AS2 (movs%W0%L0,%0,%3);
+ #endif
+ }");
+ 
+ (define_peephole
+   [
+    (set (match_operand:HI 0 "register_operand" "")
+ 	(sign_extend:HI
+ 	 (match_operand:QI 1 "memory_operand" "")))
+    (set (match_dup 0)
+ 	(and:HI (match_dup 0)
+ 		(match_operand:HI 2 "immediate_operand" "")))
+   ]
+   ""
+   "*
+ {
+       if ((INTVAL (operands[2]) & 0xff00) == 0
+           && QI_REG_P (operands[0]))
+         {
+           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
+         }
+       else
+         {
+ #ifdef INTEL_SYNTAX
+           output_asm_insn( AS2 (movsx,%1,%0), operands);
+ #else
+           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
+ #endif
+         }
+       /* Can we ignore the upper byte? */
+       if (QI_REG_P (operands[0])
+ 	  && (INTVAL (operands[2]) & 0xff00) == 0xff00)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%b0), operands);
+ 	    }
+ 	  else
+ 	    {
+ 	      operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
+ 	      output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	    }
+ 	}
+       else if (QI_REG_P (operands[0]) 
+                && (INTVAL (operands[2]) & 0xff) == 0xff)
+ 	{
+ 	  if ((INTVAL (operands[2]) & 0xff00) == 0)
+ 	    {
+ 	      operands[2] = const0_rtx;
+ 	      output_asm_insn (AS2 (mov%B0,%2,%h0), operands);
+ 	    }
+ 
+ 	  operands[1] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff);
+ 	  output_asm_insn (AS2 (and%B0,%2,%b0), operands);
+ 	}
+       else
+         {
+           output_asm_insn (AS2 (and%W0,%2,%0), operands);
+         }
+    RET;
+ }");
+ 
+ (define_peephole
+   [
+    (set (match_operand:SI 0 "register_operand" "")
+ 	(sign_extend:SI
+ 	 (match_operand:QI 1 "memory_operand" "")))
+    (set (match_dup 0)
+ 	(and:SI (match_dup 0)
+ 		(match_operand:SI 2 "immediate_operand" "")))
+   ]
+   ""
+   "*
+ {
+       if ((INTVAL (operands[2]) & 0xffffff00) == 0
+           && QI_REG_P (operands[0]))
+         {
+           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
+         }
+       else
+         {
+ #ifdef INTEL_SYNTAX
+           output_asm_insn( AS2 (movsx,%1,%0), operands);
+ #else
+           output_asm_insn( AS2 (movs%B0%L0,%1,%0), operands);
+ #endif
+         }
+       output_asm_insn (AS2 (and%L0,%2,%0), operands);
+    RET;
+ }");
+ 
+ (define_peephole
+   [
+    (set (match_operand:SI 0 "register_operand" "")
+ 	(sign_extend:SI
+ 	 (match_operand:HI 1 "memory_operand" "")))
+    (set (match_dup 0)
+ 	(and:SI (match_dup 0)
+ 		(match_operand:SI 2 "immediate_operand" "")))
+   ]
+   ""
+   "*
+ {
+       if ((INTVAL (operands[2]) & 0xffffff00) == 0
+           && QI_REG_P (operands[0]))
+         {
+           output_asm_insn (AS2 (mov%B0,%b1,%b0), operands);
+         }
+       else if ((INTVAL (operands[2]) & 0xffff0000) == 0)
+         {
+           output_asm_insn (AS2 (mov%W0,%h1,%h0), operands);
+         }
+       else
+         {
+ #ifdef INTEL_SYNTAX
+           output_asm_insn( AS2 (movsx,%1,%0), operands);
+ #else
+           output_asm_insn( AS2 (movs%B0%W0,%1,%0), operands);
+ #endif
+         }
+       output_asm_insn (AS2 (and%L0,%2,%0), operands);
+    RET;
+ }");
diff -rNci gcc-2.7.2/config.sub gcc-2.7.2p/config.sub
*** gcc-2.7.2/config.sub	Thu Jun 15 21:01:49 1995
--- gcc-2.7.2p/config.sub	Tue Jan 23 09:25:24 1996
***************
*** 130,141 ****
  	# Recognize the basic CPU types without company name.
  	# Some are omitted here because they have special meanings below.
  	tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
! 		| arme[lb] | pyramid \
  		| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
  		| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
  		| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
  		| pdp11 | mips64el | mips64orion | mips64orionel \
! 		| sparc)
  		basic_machine=$basic_machine-unknown
  		;;
  	# Object if more than one company name word.
--- 130,141 ----
  	# Recognize the basic CPU types without company name.
  	# Some are omitted here because they have special meanings below.
  	tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
! 		| pentium | arme[lb] | pyramid \
  		| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
  		| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
  		| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
  		| pdp11 | mips64el | mips64orion | mips64orionel \
! 		| sparc )
  		basic_machine=$basic_machine-unknown
  		;;
  	# Object if more than one company name word.
***************
*** 145,157 ****
  		;;
  	# Recognize the basic CPU types with company name.
  	vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
! 	      | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
  	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
  	      | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
  	      | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
  	      | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
  	      | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
! 	      | mips64el-* | mips64orion-* | mips64orionel-*)
  		;;
  	# Recognize the various machine names and aliases which stand
  	# for a CPU type and a company and sometimes even an OS.
--- 145,157 ----
  		;;
  	# Recognize the basic CPU types with company name.
  	vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
! 	      | pentium-* | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
  	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
  	      | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
  	      | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
  	      | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
  	      | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
! 	      | mips64el-* | mips64orion-* | mips64orionel-* )
  		;;
  	# Recognize the various machine names and aliases which stand
  	# for a CPU type and a company and sometimes even an OS.
***************
*** 312,329 ****
--- 312,345 ----
  		basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  		os=-sysv32
  		;;
+ 	pentiumv32)
+ 		basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
+ 		os=-sysv32
+ 		;;
  	i[345]86v4*)
  		basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  		os=-sysv4
  		;;
+   pentiumv4*)
+       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
+       os=-sysv4
+       ;;
  	i[345]86v)
  		basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  		os=-sysv
  		;;
+   pentiumv)
+       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
+       os=-sysv
+       ;;
  	i[345]86sol2)
  		basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
  		os=-solaris2
  		;;
+   pentiumsol2)
+       basic_machine=`echo $1 | sed -e 's/pentium.*/pentium-unknown/'`
+       os=-solaris2
+       ;;
  	iris | iris4d)
  		basic_machine=mips-sgi
  		case $os in
diff -rNci gcc-2.7.2/configure gcc-2.7.2p/configure
*** gcc-2.7.2/configure	Sun Nov 26 19:39:15 1995
--- gcc-2.7.2p/configure	Tue Jan 23 09:53:19 1996
***************
*** 844,850 ****
  		xm_file=i370/xm-mvs.h
  		out_file=i370/mvs370.c
  		;;
! 	i[345]86-ibm-aix*)		# IBM PS/2 running AIX
  		cpu_type=i386
                  if [ x$gas = xyes ]
  		then
--- 844,850 ----
  		xm_file=i370/xm-mvs.h
  		out_file=i370/mvs370.c
  		;;
! 	pentium-ibm-aix* | i[345]86-ibm-aix*)		# IBM PS/2 running AIX
  		cpu_type=i386
                  if [ x$gas = xyes ]
  		then
***************
*** 867,873 ****
  		extra_parts="crtbegin.o crtend.o"
  		tmake_file=i386/t-crtpic
  		;;
! 	i[345]86-next-*)
  		cpu_type=i386
  		tm_file=i386/next.h
  		out_file=i386/next.c
--- 867,873 ----
  		extra_parts="crtbegin.o crtend.o"
  		tmake_file=i386/t-crtpic
  		;;
! 	pentium-next-* | i[345]86-next-*)
  		cpu_type=i386
  		tm_file=i386/next.h
  		out_file=i386/next.c
***************
*** 875,881 ****
  		tmake_file=i386/t-next
  		xmake_file=i386/x-next
  		;;
! 	i[345]86-sequent-bsd*) 		# 80386 from Sequent
  		cpu_type=i386
  		use_collect2=yes
  		if [ x$gas = xyes ]
--- 875,881 ----
  		tmake_file=i386/t-next
  		xmake_file=i386/x-next
  		;;
! 	pentium-sequent-bsd* | i[345]86-sequent-bsd*) 		# 80386 from Sequent
  		cpu_type=i386
  		use_collect2=yes
  		if [ x$gas = xyes ]
***************
*** 885,891 ****
  			tm_file=i386/sequent.h
  		fi
  		;;
! 	i[345]86-sequent-ptx1*)
  		cpu_type=i386
  		xm_file=i386/xm-sysv3.h
  		xmake_file=i386/x-sysv3
--- 885,891 ----
  			tm_file=i386/sequent.h
  		fi
  		;;
! 	pentium-sequent-ptx1* | i[345]86-sequent-ptx1*)
  		cpu_type=i386
  		xm_file=i386/xm-sysv3.h
  		xmake_file=i386/x-sysv3
***************
*** 912,928 ****
  		tm_file=i386/sun.h
  		use_collect2=yes
  		;;
  	i[345]86-*-aout*)
  		cpu_type=i386
  		tm_file=i386/i386-aout.h
  		tmake_file=i386/t-i386bare
  		;;
- 	i[345]86-*-bsdi* | i[345]86-*-bsd386*)
- 		cpu_type=i386
- 		tm_file=i386/bsd386.h
- 		xm_file=i386/xm-bsd386.h
- #		tmake_file=t-libc-ok
- 		;;
  	i[345]86-*-bsd*)
  		cpu_type=i386
  		tm_file=i386/386bsd.h
--- 912,927 ----
  		tm_file=i386/sun.h
  		use_collect2=yes
  		;;
+ 	pentium-*-bsd* | i[345]86-*-bsdi* | i[345]86-*-bsd386*)
+ 		cpu_type=i386
+ 		tm_file=i386/bsd386.h
+ #		tmake_file=t-libc-ok
+ 		;;
  	i[345]86-*-aout*)
  		cpu_type=i386
  		tm_file=i386/i386-aout.h
  		tmake_file=i386/t-i386bare
  		;;
  	i[345]86-*-bsd*)
  		cpu_type=i386
  		tm_file=i386/386bsd.h
***************
*** 931,960 ****
  # Next line turned off because both 386BSD and BSD/386 use GNU ld.
  #		use_collect2=yes
  		;;
! 	i[345]86-*-freebsd*)
  		cpu_type=i386
  		tm_file=i386/freebsd.h
- 		xm_file=i386/xm-freebsd.h
  		# On FreeBSD, the headers are already ok.
  		fixincludes=Makefile.in
  		xmake_file=i386/x-freebsd
  		;;
! 	i[345]86-*-netbsd*)
  		cpu_type=i386
! 		tm_file=i386/netbsd.h
! 		xm_file=i386/xm-netbsd.h
  		# On NetBSD, the headers are already okay.
  		fixincludes=Makefile.in
- 		tmake_file=t-libc-ok
  		xmake_file=x-netbsd
  		;;
! 	i[345]86-*-coff*)
  		cpu_type=i386
! 		tm_file=i386/i386-coff.h
! 		tmake_file=i386/t-i386bare
! 		;;
! 	i[345]86-*-gnu*)
! 		cpu_type=i386	# GNU supports this CPU; rest done below.
  		;;
  	i[345]86-*-isc*)		# 80386 running ISC system
  		cpu_type=i386
--- 930,959 ----
  # Next line turned off because both 386BSD and BSD/386 use GNU ld.
  #		use_collect2=yes
  		;;
! 	pentium-*-freebsd* | i[345]86-*-freebsd*)
  		cpu_type=i386
  		tm_file=i386/freebsd.h
  		# On FreeBSD, the headers are already ok.
  		fixincludes=Makefile.in
  		xmake_file=i386/x-freebsd
  		;;
! 	pentium-*-netbsd* | i[345]86-*-netbsd*)
  		cpu_type=i386
! 		tm_file=i386/netbsd-i386.h
  		# On NetBSD, the headers are already okay.
  		fixincludes=Makefile.in
  		xmake_file=x-netbsd
  		;;
! 	pentium-*-gnu* | i[345]86-*-gnu*)
  		cpu_type=i386
! 		xm_file=i386/xm-gnu.h
! 		tm_file=i386/gnu.h
! 		tmake_file=t-libc-ok
! 		# GNU tools are the only tools.
! 		gnu_ld=yes
! 		gas=yes
! 		# On GNU, the headers are already okay.
! 		fixincludes=Makefile.in
  		;;
  	i[345]86-*-isc*)		# 80386 running ISC system
  		cpu_type=i386
***************
*** 972,1021 ****
  		then
  			tm_file=i386/iscdbx.h
  			tmake_file=i386/t-svr3dbx
- 			extra_parts="crtbegin.o crtend.o svr3.ifile svr3z.ifile"
  		else
  			tm_file=i386/isccoff.h
- 			tmake_file=i386/t-crtstuff
  			extra_parts="crtbegin.o crtend.o"
  		fi
  		install_headers_dir=install-headers-cpio
  		broken_install=yes
  		;;
! 	i[345]86-*-linux*oldld*)	# Intel 80386's running Linux
! 		cpu_type=i386		# with a.out format using pre BFD linkers
! 		xm_file=i386/xm-linux.h
! 		xmake_file=x-linux
! 		tm_file=i386/linux-oldld.h
! 		fixincludes=Makefile.in #On Linux, the headers are ok already.
! 		broken_install=yes
! 		gnu_ld=yes
! 		;;
! 	i[345]86-*-linux*aout*)		# Intel 80386's running Linux
! 		cpu_type=i386		# with a.out format
  		xm_file=i386/xm-linux.h
! 		xmake_file=x-linux
  		tm_file=i386/linux-aout.h
  		fixincludes=Makefile.in #On Linux, the headers are ok already.
  		broken_install=yes
- 		gnu_ld=yes
  		;;
! 	i[345]86-*-linux*)		# Intel 80386's running Linux
! 		cpu_type=i386		# with ELF format
  		xm_file=i386/xm-linux.h
! 		xmake_file=x-linux
  		tm_file=i386/linux.h
  		fixincludes=Makefile.in #On Linux, the headers are ok already.
  		broken_install=yes
- 		gnu_ld=yes
- 		# Don't use it. Linux uses a slightly different one.
- 		# The real one comes with the Linux C library.
- 		#extra_parts="crtbegin.o crtend.o"
  		;;
!       i[345]86-go32-msdos | i[345]86-*-go32)
!               cpu_type=i386
!               tm_file=i386/go32.h
!               ;;
! 	i[345]86-*-lynxos*)
  		cpu_type=i386
  		if [ x$gas = xyes ]
  		then
--- 971,1000 ----
  		then
  			tm_file=i386/iscdbx.h
  			tmake_file=i386/t-svr3dbx
  		else
  			tm_file=i386/isccoff.h
  			extra_parts="crtbegin.o crtend.o"
  		fi
  		install_headers_dir=install-headers-cpio
  		broken_install=yes
  		;;
! 	pentium-*-linuxaout | i[345]86-*-linuxaout)		# Intel 80386's running Linux
! 		cpu_type=i386
  		xm_file=i386/xm-linux.h
! 		xmake_file=i386/x-linux
  		tm_file=i386/linux-aout.h
  		fixincludes=Makefile.in #On Linux, the headers are ok already.
  		broken_install=yes
  		;;
! 	pentium-*-linux* | i[345]86-*-linux*)		# Intel 80386's running Linux
! 		cpu_type=i386
  		xm_file=i386/xm-linux.h
! 		xmake_file=i386/x-linux
  		tm_file=i386/linux.h
  		fixincludes=Makefile.in #On Linux, the headers are ok already.
  		broken_install=yes
  		;;
! 	pentium-*-lynxos* | i[345]86-*-lynxos*)
  		cpu_type=i386
  		if [ x$gas = xyes ]
  		then
***************
*** 1027,1039 ****
  		tmake_file=i386/t-i386bare
  		xmake_file=x-lynx
  		;;
! 	i[345]86-*-mach*)
  		cpu_type=i386
  		tm_file=i386/mach.h
  #		tmake_file=t-libc-ok
  		use_collect2=yes
  		;;
! 	i[345]86-*-osfrose*)		# 386 using OSF/rose
  		cpu_type=i386
                  if [ x$elf = xyes ]
  		then
--- 1006,1018 ----
  		tmake_file=i386/t-i386bare
  		xmake_file=x-lynx
  		;;
! 	pentium-*-mach* | i[345]86-*-mach*)
  		cpu_type=i386
  		tm_file=i386/mach.h
  #		tmake_file=t-libc-ok
  		use_collect2=yes
  		;;
! 	pentium-*-osfrose* | i[345]86-*-osfrose*)		# 386 using OSF/rose
  		cpu_type=i386
                  if [ x$elf = xyes ]
  		then
***************
*** 1093,1099 ****
  		fixincludes=fixinc.svr4
  		broken_install=yes
  		;;
! 	i[345]86-*-sysv4*)		# Intel 80386's running system V.4
  		cpu_type=i386
  		xm_file=i386/xm-sysv4.h
  		if [ x$stabs = xyes ]
--- 1072,1078 ----
  		fixincludes=fixinc.svr4
  		broken_install=yes
  		;;
! 	pentium-*-sysv4* | i[345]86-*-sysv4*)	# Intel 80386's running system V.4
  		cpu_type=i386
  		xm_file=i386/xm-sysv4.h
  		if [ x$stabs = xyes ]
***************
*** 1106,1112 ****
  		xmake_file=x-svr4
  		extra_parts="crtbegin.o crtend.o"
  		;;
! 	i[345]86-*-sysv*)		# Intel 80386's running system V
  		cpu_type=i386
  		xm_file=i386/xm-sysv3.h
  		xmake_file=i386/x-sysv3
--- 1085,1091 ----
  		xmake_file=x-svr4
  		extra_parts="crtbegin.o crtend.o"
  		;;
! 	pentium-*-sysv* | i[345]86-*-sysv*)		# Intel 80386's running system V
  		cpu_type=i386
  		xm_file=i386/xm-sysv3.h
  		xmake_file=i386/x-sysv3
***************
*** 1116,1152 ****
  			then
  				tm_file=i386/svr3dbx.h
  				tmake_file=i386/t-svr3dbx
- 				extra_parts="svr3.ifile svr3z.rfile"
  			else
  				tm_file=i386/svr3gas.h
  				extra_parts="crtbegin.o crtend.o"
- 				tmake_file=i386/t-crtstuff
  			fi
  		else
  			tm_file=i386/sysv3.h
  			extra_parts="crtbegin.o crtend.o"
- 			tmake_file=i386/t-crtstuff
  		fi
  		;;
! 	i386-*-vsta)			# Intel 80386's running VSTa kernel
! 		xm_file=i386/xm-vsta.h
! 		tm_file=i386/vsta.h
! 		tmake_file=i386/t-vsta
! 		xmake_file=i386/x-vsta
! 		;;
! 	i[345]86-*-winnt3*)
  		cpu_type=i386
! 		tm_file=i386/win-nt.h
  		out_file=i386/i386.c
  		xm_file=i386/xm-winnt.h
! 		xmake_file=winnt/x-winnt
! 		tmake_file=i386/t-winnt
! 		extra_objs="winnt.o oldnames.o"
! 		extra_gcc_objs="spawnv.o oldnames.o"
! 		fixincludes=fixinc.winnt
  		if [ x$gnu_ld != xyes ]
  		then
! 			extra_programs=ld.exe
  		fi
  		;;
  	i860-alliant-*)		# Alliant FX/2800
--- 1095,1118 ----
  			then
  				tm_file=i386/svr3dbx.h
  				tmake_file=i386/t-svr3dbx
  			else
  				tm_file=i386/svr3gas.h
  				extra_parts="crtbegin.o crtend.o"
  			fi
  		else
  			tm_file=i386/sysv3.h
  			extra_parts="crtbegin.o crtend.o"
  		fi
  		;;
! 	pentium-*-winnt3* | i[345]86-*-winnt3*)
  		cpu_type=i386
! 		tm_file=i386/winnt.h
  		out_file=i386/i386.c
  		xm_file=i386/xm-winnt.h
! 		xmake_file=i386/x-winnt
  		if [ x$gnu_ld != xyes ]
  		then
! 			extra_programs=ld
  		fi
  		;;
  	i860-alliant-*)		# Alliant FX/2800
***************
*** 2411,2420 ****
  	esac
  
  	# Distinguish i386 from i486/i586.
! 	# ??? For the moment we treat i586 as an i486.
  	# Also, do not run mips-tfile on MIPS if using gas.
  	case $machine in
! 	i[45]86-*-*)
  		target_cpu_default=2
  		;;
  	mips*-*-*)
--- 2377,2392 ----
  	esac
  
  	# Distinguish i386 from i486/i586.
! 	# ??? For the moment we treat i586 as an i486. (NOT!)
  	# Also, do not run mips-tfile on MIPS if using gas.
  	case $machine in
! 	pentium-*-*)
! 		target_cpu_default=4
! 		;;
! 	i586-*-*)
! 		target_cpu_default=4
! 		;;
! 	i486-*-*)
  		target_cpu_default=2
  		;;
  	mips*-*-*)
diff -rNci gcc-2.7.2/cse.c gcc-2.7.2p/cse.c
*** gcc-2.7.2/cse.c	Sun Nov 26 19:47:05 1995
--- gcc-2.7.2p/cse.c	Tue Jan 23 09:53:20 1996
***************
*** 6136,6141 ****
--- 6136,6164 ----
        sets = (struct set *) alloca (sizeof (struct set));
        sets[0].rtl = x;
  
+ /* intel1 */
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+       if (IS_STACK_MODE (DFmode) && GET_CODE (SET_SRC (x)) == CONST_DOUBLE 
+          && GET_CODE (SET_DEST (x)) == REG)
+         {
+            /* not worthwhile to hold on stack */
+ 	  rtx tem = find_reg_note (insn, REG_EQUAL, 0);
+ 	  
+ 	  /* Record the actual constant value in a REG_EQUAL note, making
+ 	     a new one if one does not already exist.  */
+ 	  if (tem)
+ 	    XEXP (tem, 0) = SET_SRC(x);
+ 	  else
+ 	    REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
+ 				        SET_SRC(x), REG_NOTES (insn));
+ 
+ 	  invalidate (SET_DEST (x), GET_MODE(x) );
+         }
+       else
+       
+ #endif
+ #endif
        /* Ignore SETs that are unconditional jumps.
  	 They never need cse processing, so this does not hurt.
  	 The reason is not efficiency but rather
***************
*** 6762,6767 ****
--- 6785,6816 ----
        if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
  	src_folded = src_const, src_folded_cost = -1;
  	  
+ #ifdef SAVE_ON_REGS
+       /* intel1 If src is of form  (reg1 OP const) and src_folded
+          is of form (reg2 OP const) and the costs are the same
+          and reg1 != reg2,
+          then bump up the cost of src_folded so that src will be
+          preferred.  The reason for this is that if reg2 is used
+          here it's life may be extended thereby increasing register
+          pressure and causing superfulous movs.  */
+       {
+         char * fmt;
+         if (src)
+           fmt = GET_RTX_FORMAT (GET_CODE (src));
+         if (src && src_folded && src_cost == src_folded_cost
+             && GET_CODE (src) == GET_CODE (src_folded) 
+             && GET_RTX_LENGTH (GET_CODE (src)) == 2
+             && fmt[0] == 'e' && fmt[1] == 'e'
+             && GET_CODE (XEXP (src, 0)) == REG
+             && GET_CODE (XEXP (src, 1)) == CONST_INT 
+             && GET_CODE (XEXP (src_folded, 0)) == REG
+             && GET_CODE (XEXP (src_folded, 1)) == CONST_INT 
+             && !rtx_equal_p (XEXP (src, 0), XEXP (src_folded, 0)))
+           {
+             src_folded_cost++;
+           }          
+       }
+ #endif
        /* Terminate loop when replacement made.  This must terminate since
           the current contents will be tested and will always be valid.  */
        while (1)
***************
*** 7205,7210 ****
--- 7254,7269 ----
  	    if (sets[i].src_elt == 0)
  	      {
  		register struct table_elt *elt;
+ 		/* intel1 */
+ 		int do_rehash=0;
+ 
+                 /* intel1 */
+ 		if(GET_CODE(src)==REG && 
+ 		   !REGNO_QTY_VALID_P (REGNO(src)))
+ 		    { /* we will want to rehash all expressions based of src since
+ 		         reg_qty[REGNO(src)] is about to change */
+ 		      do_rehash = 1;
+ 		    }
  
  		/* Note that these insert_regs calls cannot remove
  		   any of the src_elt's, because they would have failed to
diff -rNci gcc-2.7.2/expr.c gcc-2.7.2p/expr.c
*** gcc-2.7.2/expr.c	Sun Nov 26 16:18:07 1995
--- gcc-2.7.2p/expr.c	Tue Jan 23 09:53:21 1996
***************
*** 24,29 ****
--- 24,31 ----
  #include "rtl.h"
  #include "tree.h"
  #include "obstack.h"
+ /* intel1 */
+ #include "c-tree.h"
  #include "flags.h"
  #include "regs.h"
  #include "function.h"
***************
*** 8954,8959 ****
--- 8956,8967 ----
  	  && (i = floor_log2 (TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)))) >= 0
  	  && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
  	  && (type = type_for_mode (mode, 1)) != 0
+       /* intel1 */
+       && !(SLOW_SHORT_ACCESS
+          && (type == short_unsigned_type_node
+              || type == short_integer_type_node
+              || type == intHI_type_node
+              || type == unsigned_intHI_type_node))
  	  && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
  	  && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
  	      != CODE_FOR_nothing))
***************
*** 9111,9116 ****
--- 9119,9130 ----
  	type = type_for_size (bitsize, unsignedp);
  	if (! SLOW_BYTE_ACCESS
  	    && type != 0 && bitsize >= 0
+ 	    /* intel1 */
+ 	    && !(SLOW_SHORT_ACCESS 
+ 	         && (type == short_unsigned_type_node 
+ 	             || type == short_integer_type_node
+ 	             || type == intHI_type_node 
+ 	             || type == unsigned_intHI_type_node))
  	    && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
  	    && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
  		!= CODE_FOR_nothing))
diff -rNci gcc-2.7.2/flags.h gcc-2.7.2p/flags.h
*** gcc-2.7.2/flags.h	Thu Jun 15 11:34:11 1995
--- gcc-2.7.2p/flags.h	Tue Jan 23 09:25:25 1996
***************
*** 361,363 ****
--- 361,509 ----
     function.  */
  
  extern int current_function_has_nonlocal_goto;
+ 
+ /* intel1 our optimization controllers */
+ 
+ /* Optimize usage of registers for memory addresses */
+ 
+ extern int flag_opt_reg_use;
+ 
+ /* Do reduce all the mem address givs */
+ 
+ extern int flag_all_mem_givs;
+ 
+ /* Try to treat index terms of addresses as reducible mem givs */
+ 
+ extern int flag_reduce_index_givs;
+ 
+ /* After reload try to replace spill slots with equivalent registers */
+ 
+ extern int flag_peep_spills;
+ 
+ /* After reload try to optimize usage of spill slots in loops */
+ 
+ extern int flag_loop_after_global;
+ 
+ /* In optimization of loops treats jumps backwards as not nullifying
+    optimization opportunities.  */
+    
+ extern int flag_jump_back;
+ 
+ /* Do loop copy propogation */
+ 
+ extern int flag_copy_prop;
+ 
+ /* Do compare elimination */
+ 
+ extern int flag_compare_elim;
+ 
+ /* Do a mini software pipelining on stack registers */
+ 
+ extern int flag_sftwr_pipe;
+ 
+ /* Try aggressive changing of jumps taken to jumps not taken */
+ 
+ extern int flag_opt_jumps_out;
+ 
+ /* Try to replace memory operands with equivalent registers in first
+    pass of loop optimize */
+    
+ extern int flag_replace_mem;
+ 
+ /* Try to replace memory operands with equivalent stack registers in first
+    pass of loop optimize */
+    
+ extern int flag_replace_stack_mem;
+ 
+ /* After reload if a register is marked dead at a copy into another
+    register - see if the other register can be used in the first place.
+    Thereby eleiminating the copy.  */
+    
+ extern int flag_reg_reg_copy_opt;
+ 
+ /* Move stack registers that will be compared for equality off, the
+    stack before the comparison.  */
+    
+ extern int flag_do_offload;
+ 
+ /* Optimize usage of stack registers from the stack */
+ 
+ extern int flag_opt_reg_stack;
+ 
+ /* cse is sometimes detrimental - see flow.c */
+ 
+ extern int flag_correct_cse_mistakes;
+ 
+ /* Try to push loads back into loops if the loaded register has been spilled */
+ 
+ extern int flag_push_load_into_loop;
+ 
+ /* After reload use available registers to load memory operands into
+   them and use the register instead of the memory operand.  */
+   
+ extern int flag_risc;
+ 
+ /* After reload use available registers to load CONST_INTs into
+   them and then store the register instead of the CONST_INT.  */
+   
+ extern int flag_risc_const;
+ 
+ /* Allow scheduler to try to swap two instructions when the
+    first increments a register by a constant and the second
+    uses that register as a base
+ */
+ 
+ extern int flag_swap_for_agi;
+ 
+ /* A destination that was riscified should stay that way.  */
+ 
+ extern int flag_risc_mem_dest;
+ 
+ /* Try to use available registers so that a memory operand that is
+    reloaded will be reloaded into the same register.  This helps
+    loop_after_global.  */
+    
+ extern int flag_replace_reload_regs;
+ 
+ /* If the riscified instruction has not changed it's place in
+   scheduling then recombine it into a cisc instruction.  */
+   
+ extern int flag_recombine;
+ 
+ /* These negative flags needed to override optimization
+    levels which turn them on by default */
+    
+ extern int flag_no_omit_frame_pointer;
+ extern int flag_no_risc;
+ extern int flag_no_risc_const;
+ extern int flag_no_risc_mem_dest;
+ extern int flag_no_recombine;
+ /* Use the first pass of the scheduler to rearrange between
+    insns that reference stack registers.  */
+    
+ extern int flag_schedule_stack_reg_insns;
+ 
+ /* Use the first pass of the scheduler to rearrange between
+    insns that reference stack registers and those that don't
+    but not amongst themselves  */
+    
+ extern int flag_interleave_stack_non_stack;
+ 
+ /* These negative flags needed to override optimization
+    levels which turn them on by default */
+    
+ extern int flag_no_schedule_stack_reg_insns;
+ extern int flag_no_interleave_stack_non_stack;
+ 
+ extern int flag_sign_extension_elim;
+ 
+ /* Try to lift memory disambiguated memory operands that are stored
+    to in a loop into a register for the duration of the loop.  */
+    
+ extern int flag_lift_stores;
+ 
+ /* As above but do the disambiguation at runtime. i.e. there
+    will be two copies of the loop, one disambiguated one not,
+    And the decision of which one to run will be made at runtime.  */
+    
+ extern int flag_runtime_lift_stores;
diff -rNci gcc-2.7.2/flow.c gcc-2.7.2p/flow.c
*** gcc-2.7.2/flow.c	Mon Aug 28 10:23:34 1995
--- gcc-2.7.2p/flow.c	Tue Jan 23 09:35:24 1996
***************
*** 286,299 ****
  static HARD_REG_SET elim_reg_set;
  
  /* Forward declarations */
! static void find_basic_blocks		PROTO((rtx, rtx));
  static int uses_reg_or_mem		PROTO((rtx));
  static void mark_label_ref		PROTO((rtx, rtx, int));
! static void life_analysis		PROTO((rtx, int));
  void allocate_for_life_analysis		PROTO((void));
! static void init_regset_vector		PROTO((regset *, regset, int, int));
  static void propagate_block		PROTO((regset, rtx, rtx, int, 
! 					       regset, int));
  static rtx flow_delete_insn		PROTO((rtx));
  static int insn_dead_p			PROTO((rtx, regset, int));
  static int libcall_dead_p		PROTO((rtx, regset, rtx, rtx));
--- 286,299 ----
  static HARD_REG_SET elim_reg_set;
  
  /* Forward declarations */
! static void find_basic_blocks		PROTO((rtx, rtx, int));
  static int uses_reg_or_mem		PROTO((rtx));
  static void mark_label_ref		PROTO((rtx, rtx, int));
! static void life_analysis		PROTO((rtx, int, int));
  void allocate_for_life_analysis		PROTO((void));
! /* intel2 static */ void init_regset_vector		PROTO((regset *, regset, int, int));
  static void propagate_block		PROTO((regset, rtx, rtx, int, 
! 					       regset, int, int));
  static rtx flow_delete_insn		PROTO((rtx));
  static int insn_dead_p			PROTO((rtx, regset, int));
  static int libcall_dead_p		PROTO((rtx, regset, rtx, rtx));
***************
*** 307,322 ****
--- 307,333 ----
  static int try_pre_increment		PROTO((rtx, rtx, HOST_WIDE_INT));
  static rtx find_use_as_address		PROTO((rtx, rtx, HOST_WIDE_INT));
  void dump_flow_info			PROTO((FILE *));
+ /* intel1 */
+ static void correct_cse_mistakes ();
+ static void count_reg_uses ();
+ static void do_correction ();
  
  /* Find basic blocks of the current function and perform data flow analysis.
     F is the first insn of the function and NREGS the number of register numbers
     in use.  */
  
  void
+ /*
  flow_analysis (f, nregs, file)
+ */
+ /* intel2 - added the change_f flag to disable changes to the insns, when called
+  * by memory_simplify. Don't apply any change to an insn if this flag == 0
+  */
+ flow_analysis (f, nregs, file, change_f)
       rtx f;
       int nregs;
       FILE *file;
+ 	 int change_f; /* intel2 */
  {
    register rtx insn;
    register int i;
***************
*** 326,331 ****
--- 337,350 ----
    static struct {int from, to; } eliminables[] = ELIMINABLE_REGS;
  #endif
  
+   /* intel1 */
+ #ifdef SPARE_REGS
+   if (change_f && flag_opt_reg_stack)
+     {
+       nregs += SPARE_REGS;
+     }
+ #endif
+ 
    /* Record which registers will be eliminated.  We use this in
       mark_used_regs. */
  
***************
*** 372,380 ****
    /* Allocate some tables that last till end of compiling this function
       and some needed only in find_basic_blocks and life_analysis.  */
  
!   n_basic_blocks = i;
!   basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
!   basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
    basic_block_drops_in = (char *) alloca (n_basic_blocks);
    basic_block_loop_depth = (short *) alloca (n_basic_blocks * sizeof (short));
    uid_block_number
--- 391,403 ----
    /* Allocate some tables that last till end of compiling this function
       and some needed only in find_basic_blocks and life_analysis.  */
  
!   if (change_f || (n_basic_blocks!=i)) 
!   /* intel2 if change_f is 0 we may have already allocated basic blocks */
!     {
!       n_basic_blocks = i;
!       basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
!       basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
!     }
    basic_block_drops_in = (char *) alloca (n_basic_blocks);
    basic_block_loop_depth = (short *) alloca (n_basic_blocks * sizeof (short));
    uid_block_number
***************
*** 382,392 ****
    uid_volatile = (char *) alloca (max_uid_for_flow + 1);
    bzero (uid_volatile, max_uid_for_flow + 1);
  
!   find_basic_blocks (f, nonlocal_label_list);
!   life_analysis (f, nregs);
    if (file)
      dump_flow_info (file);
  
    basic_block_drops_in = 0;
    uid_block_number = 0;
    basic_block_loop_depth = 0;
--- 405,420 ----
    uid_volatile = (char *) alloca (max_uid_for_flow + 1);
    bzero (uid_volatile, max_uid_for_flow + 1);
  
!   find_basic_blocks (f, nonlocal_label_list /* intel2: */, change_f);
!   life_analysis (f, nregs /* intel2: */, change_f);
    if (file)
      dump_flow_info (file);
  
+   /* intel1 */
+   if (flag_correct_cse_mistakes && change_f)
+     {
+       correct_cse_mistakes (f, nregs, file);
+     }
    basic_block_drops_in = 0;
    uid_block_number = 0;
    basic_block_loop_depth = 0;
***************
*** 400,407 ****
     NONLOCAL_LABEL_LIST is the same local variable from flow_analysis.  */
  
  static void
! find_basic_blocks (f, nonlocal_label_list)
       rtx f, nonlocal_label_list;
  {
    register rtx insn;
    register int i;
--- 428,436 ----
     NONLOCAL_LABEL_LIST is the same local variable from flow_analysis.  */
  
  static void
! find_basic_blocks (f, nonlocal_label_list /* intel2: */, change_f)
       rtx f, nonlocal_label_list;
+      int change_f;/* intel2 */
  {
    register rtx insn;
    register int i;
***************
*** 634,642 ****
  	 They can occur because jump_optimize does not recognize
  	 unreachable loops as unreachable.  */
  
!       deleted = 0;
        for (i = 0; i < n_basic_blocks; i++)
! 	if (!block_live[i])
  	  {
  	    deleted++;
  
--- 663,671 ----
  	 They can occur because jump_optimize does not recognize
  	 unreachable loops as unreachable.  */
  
!       deleted=0;
        for (i = 0; i < n_basic_blocks; i++)
! 	if (!block_live[i] /* intel2: */ && change_f)
  	  {
  	    deleted++;
  
***************
*** 874,882 ****
     regset_size and regset_bytes are also set here.  */
  
  static void
! life_analysis (f, nregs)
       rtx f;
       int nregs;
  {
    register regset tem;
    int first_pass;
--- 903,912 ----
     regset_size and regset_bytes are also set here.  */
  
  static void
! life_analysis (f, nregs /* intel2: */, change_f)
       rtx f;
       int nregs;
+      int change_f;	/* intel2 */
  {
    register regset tem;
    int first_pass;
***************
*** 904,911 ****
  
    max_regno = nregs;
  
-   bzero (regs_ever_live, sizeof regs_ever_live);
  
    /* Allocate and zero out many data structures
       that will record the data from lifetime analysis.  */
  
--- 934,947 ----
  
    max_regno = nregs;
  
  
+   /* intel2 - begin */
+   /* Dont reset the regs_ever_live array if called from memory_simplify */
+   if (change_f)
+     {
+       /* intel2 - end */
+       bzero (regs_ever_live, sizeof regs_ever_live);
+     }
    /* Allocate and zero out many data structures
       that will record the data from lifetime analysis.  */
  
***************
*** 950,959 ****
    for (insn = f; insn; insn = NEXT_INSN (insn))
      {
        enum rtx_code code1 = GET_CODE (insn);
!       if (code1 == CALL_INSN)
  	INSN_VOLATILE (insn) = 1;
        else if (code1 == INSN || code1 == JUMP_INSN)
  	{
  	  /* Delete (in effect) any obvious no-op moves.  */
  	  if (GET_CODE (PATTERN (insn)) == SET
  	      && GET_CODE (SET_DEST (PATTERN (insn))) == REG
--- 986,1017 ----
    for (insn = f; insn; insn = NEXT_INSN (insn))
      {
        enum rtx_code code1 = GET_CODE (insn);
!       if (code1 == CALL_INSN /* intel2: */ && change_f)
  	INSN_VOLATILE (insn) = 1;
        else if (code1 == INSN || code1 == JUMP_INSN)
  	{
+ 		/* intel2 - begin */
+ 		/* if change_f is reset, i.e. we are called from memory_simplify, and
+ 		 * therefore we would like to update the insn's REG_DEAD notes.
+ 		 * If we find a REG_DEAD note, we remove it here.
+ 		 */
+ 		if (!change_f)
+ 		{
+ 			register rtx note;
+ 			
+ 
+ 			for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ 				if (REG_NOTE_KIND (note) == REG_DEAD
+ 				    || REG_NOTE_KIND (note) == REG_UNUSED)
+ 					remove_note(insn, note);
+ 		} 
+ 		/* intel2 - end */
+ 
+ 
+ /* intel2 - begin */
+ 		if (change_f)
+ 		{
+ /* intel2 - end */
  	  /* Delete (in effect) any obvious no-op moves.  */
  	  if (GET_CODE (PATTERN (insn)) == SET
  	      && GET_CODE (SET_DEST (PATTERN (insn))) == REG
***************
*** 1014,1019 ****
--- 1072,1080 ----
  #endif
  		   && XEXP (SET_SRC (PATTERN (insn)), 0) == stack_pointer_rtx)
  	    INSN_VOLATILE (insn) = 1;
+ 		/* intel2 - begin */
+ 		} /* if (change_f) */
+ 		/* intel2 - end */
  	}
      }
  
***************
*** 1154,1160 ****
  			       basic_block_head[i], basic_block_end[i], 0,
  			       first_pass ? basic_block_significant[i]
  			       : (regset) 0,
! 			       i);
  	    }
  
  	  {
--- 1215,1221 ----
  			       basic_block_head[i], basic_block_end[i], 0,
  			       first_pass ? basic_block_significant[i]
  			       : (regset) 0,
! 			       i/* intel2: */, change_f);
  	    }
  
  	  {
***************
*** 1219,1225 ****
      {
        propagate_block (basic_block_live_at_end[i],
  		       basic_block_head[i], basic_block_end[i], 1,
! 		       (regset) 0, i);
  #ifdef USE_C_ALLOCA
        alloca (0);
  #endif
--- 1280,1286 ----
      {
        propagate_block (basic_block_live_at_end[i],
  		       basic_block_head[i], basic_block_end[i], 1,
! 		       (regset) 0, i/* intel2: */, change_f);
  #ifdef USE_C_ALLOCA
        alloca (0);
  #endif
***************
*** 1316,1322 ****
     SPACE is of type regset, but it is really as long as NELTS regsets.
     BYTES_PER_ELT is the number of bytes in one regset.  */
  
! static void
  init_regset_vector (vector, space, nelts, bytes_per_elt)
       regset *vector;
       regset space;
--- 1377,1383 ----
     SPACE is of type regset, but it is really as long as NELTS regsets.
     BYTES_PER_ELT is the number of bytes in one regset.  */
  
! /* intel2 static */ void
  init_regset_vector (vector, space, nelts, bytes_per_elt)
       regset *vector;
       regset space;
***************
*** 1353,1365 ****
     BNUM is the number of the basic block.  */
  
  static void
! propagate_block (old, first, last, final, significant, bnum)
       register regset old;
       rtx first;
       rtx last;
       int final;
       regset significant;
!      int bnum;
  {
    register rtx insn;
    rtx prev;
--- 1414,1426 ----
     BNUM is the number of the basic block.  */
  
  static void
! propagate_block (old, first, last, final, significant, bnum /* intel2: */, change_f)
       register regset old;
       rtx first;
       rtx last;
       int final;
       regset significant;
!      int bnum /* intel2: */, change_f;
  {
    register rtx insn;
    rtx prev;
***************
*** 1403,1409 ****
  	loop_depth--;
      }
  
!   if (final)
      {
        register int i, offset;
        REGSET_ELT_TYPE bit;
--- 1464,1470 ----
  	loop_depth--;
      }
  
!   if (final /* intel2: */ && change_f)
      {
        register int i, offset;
        REGSET_ELT_TYPE bit;
***************
*** 1487,1493 ****
  	     "delete" it by turning it into a NOTE of type NOTE_INSN_DELETED.
  	     We could really delete it with delete_insn, but that
  	     can cause trouble for first or last insn in a basic block.  */
! 	  if (final && insn_is_dead)
  	    {
  	      PUT_CODE (insn, NOTE);
  	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
--- 1548,1554 ----
  	     "delete" it by turning it into a NOTE of type NOTE_INSN_DELETED.
  	     We could really delete it with delete_insn, but that
  	     can cause trouble for first or last insn in a basic block.  */
! 	  if (final /* intel2: */ && change_f && insn_is_dead)
  	    {
  	      PUT_CODE (insn, NOTE);
  	      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
***************
*** 1529,1535 ****
  	  {
  	    register rtx x = PATTERN (insn);
  	    /* Does this instruction increment or decrement a register?  */
! 	    if (final && GET_CODE (x) == SET
  		&& GET_CODE (SET_DEST (x)) == REG
  		&& (GET_CODE (SET_SRC (x)) == PLUS
  		    || GET_CODE (SET_SRC (x)) == MINUS)
--- 1590,1596 ----
  	  {
  	    register rtx x = PATTERN (insn);
  	    /* Does this instruction increment or decrement a register?  */
! 	    if (final /* intel2: */ && change_f && GET_CODE (x) == SET
  		&& GET_CODE (SET_DEST (x)) == REG
  		&& (GET_CODE (SET_SRC (x)) == PLUS
  		    || GET_CODE (SET_SRC (x)) == MINUS)
***************
*** 1573,1579 ****
  		 live.  */
  
  	      mark_set_regs (old, dead, PATTERN (insn),
! 			     final ? insn : NULL_RTX, significant);
  
  	      /* If an insn doesn't use CC0, it becomes dead since we 
  		 assume that every insn clobbers it.  So show it dead here;
--- 1634,1640 ----
  		 live.  */
  
  	      mark_set_regs (old, dead, PATTERN (insn),
! 			     (final /* intel2: */ && change_f) ? insn : NULL_RTX, significant);
  
  	      /* If an insn doesn't use CC0, it becomes dead since we 
  		 assume that every insn clobbers it.  So show it dead here;
***************
*** 1637,1643 ****
  		  old[i] |= live[i];
  		}
  
! 	      if (GET_CODE (insn) == CALL_INSN && final)
  		{
  		  /* Any regs live at the time of a call instruction
  		     must not go in a register clobbered by calls.
--- 1698,1704 ----
  		  old[i] |= live[i];
  		}
  
! 	      if (GET_CODE (insn) == CALL_INSN && final /* intel2: */ && change_f)
  		{
  		  /* Any regs live at the time of a call instruction
  		     must not go in a register clobbered by calls.
***************
*** 1655,1661 ****
  	     into MAXLIVE and REGS_SOMETIMES_LIVE.
  	     Also update counts of how many insns each reg is live at.  */
  
! 	  if (final)
  	    {
  	      for (i = 0; i < regset_size; i++)
  		{
--- 1716,1722 ----
  	     into MAXLIVE and REGS_SOMETIMES_LIVE.
  	     Also update counts of how many insns each reg is live at.  */
  
! 	  if (final /* intel2: */ && change_f)
  	    {
  	      for (i = 0; i < regset_size; i++)
  		{
***************
*** 2878,2883 ****
--- 2939,2949 ----
  {
    register int i;
    static char *reg_class_names[] = REG_CLASS_NAMES;
+   /* intel1 */
+ #ifdef SPARE_REGS
+   int max_regno;
+   max_regno = max_reg_num();
+ #endif
  
    fprintf (file, "%d registers.\n", max_regno);
  
***************
*** 2954,2956 ****
--- 3020,3613 ----
      }
    fprintf (file, "\n");
  }
+ 
+ /* intel1 */
+ /* Information about registers */
+ struct regopt_info
+ {
+   rtx insn_set;			/* If non NULL then the insn that loads the register
+                           with it's current value */
+   int num_uses_copied;		/* To count if the reg setter has been copied to
+                           each of the uses */
+   char copied_for_src;          /* Set per insn if the insn_set has been copied
+                           as a result of analysis on the src */
+ };
+ static struct regopt_info *rinfo;
+ 
+ /* Count the number of new sets of the register */
+ static int *my_reg_n_sets;
+ 
+ /* Count the number of times a register is used in an insn */
+ static int *regs_in_body;
+ 
+ /* Count the number of times a register is used in a function */
+ static int *reg_n_uses;
+ 
+ /* Copied from sched.c
+    Return the INSN_LIST containing INSN in LIST, or NULL
+    if LIST does not contain INSN.  */
+ #ifndef __GNUC__
+ #define __inline
+ #endif
+ 
+ __inline static rtx
+ find_insn_list (insn, list)
+      rtx insn;
+      rtx list;
+ {
+   while (list)
+     {
+       if (XEXP (list, 0) == insn)
+ 	return list;
+       list = XEXP (list, 1);
+     }
+   return 0;
+ }
+ 
+ /*
+   Sometimes cse is done where it is detremental. Consider register 23
+   in the following insn stream:
+ 
+ (insn 18 65 82 (set (reg/v:SI 23)
+         (plus:SI (reg/v:SI 22)
+             (const_int -4501))) 32 {movsi+1} (nil)
+     (nil))
+ 
+ (insn 82 18 83 (set (cc0)
+         (compare:CC (reg/v:SI 22)
+             (const_int 4500))) 6 {cmpsi_cc} (nil)
+     (nil))
+ 
+ (jump_insn 83 82 90 (set (pc)
+         (if_then_else (gt (cc0)
+                 (const_int 0))
+             (label_ref 63)
+             (pc))) 185 {bgt+1} (nil)
+     (nil))
+ 
+ (note 90 83 91 "" NOTE_INSN_DELETED)
+ 
+ (insn 91 90 93 (set (reg:SI 32)
+         (ashift:SI (reg/v:SI 23)
+             (const_int 2))) 136 {ashlsi3} (nil)
+     (expr_list:REG_DEAD (reg/v:SI 23)
+         (nil)))
+ 
+   reg 23 appears in insn 91 as a result of cse, before cse insn 90
+   and 91 were:
+ 
+ (insn 90 83 91 (set (reg:SI 33)
+         (plus:SI (reg/v:SI 22)
+             (const_int -4501))) -1 (nil)
+     (nil))
+ 
+ (insn 91 90 93 (set (reg:SI 34)
+         (ashift:SI (reg:SI 33)
+             (const_int 2))) -1 (nil)
+     (nil))
+ 
+   since reg 23 does not appear anywhere else in the rtl and it is dead
+   at insn 91 it would be better to move insn 18 to after insn 90, thus
+   allowing the combiner to combine insn 18 into 91.
+ 
+ */
+ static void
+ correct_cse_mistakes (f, cur_max_reg, dump_file)
+      rtx f;
+      int cur_max_reg;
+      FILE *dump_file;
+ {
+   rtx insn, src, dest, insn_set, note;
+   struct regs_mentioned *header, *a_reg_used;
+   int num_regs, recog_ok, i, regno;
+   char *storage1, *storage2;
+ 
+   rinfo =
+     (struct regopt_info *) alloca ((cur_max_reg) * sizeof (struct regopt_info));
+   bzero (rinfo, (cur_max_reg) * sizeof (struct regopt_info));
+   reg_n_uses = (int *) alloca ((cur_max_reg) * sizeof (int));
+   bzero (reg_n_uses, (cur_max_reg) * sizeof (int));
+   regs_in_body = (int *) alloca ((cur_max_reg) * sizeof (int));
+   bzero (regs_in_body, (cur_max_reg) * sizeof (int));
+   my_reg_n_sets = (int *) alloca ((cur_max_reg) * sizeof (int));
+   bzero (my_reg_n_sets, (cur_max_reg) * sizeof (int));
+ 
+   if (dump_file)
+     fprintf (dump_file, "\ndoing correct_cse_mistakes:\n\n");
+   insn = f;
+   while (insn)
+     {
+       if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
+ 	  || GET_CODE (insn) == CALL_INSN)
+ 	{
+ 	  count_reg_uses (PATTERN (insn), reg_n_uses);
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   insn = f;
+   while (insn)
+     {
+       switch (GET_CODE (insn))
+ 	{
+ 
+ 	case CALL_INSN:
+ 	  /* Don't want to change reg_n_calls_crosses */
+ 	  bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	  break;
+ 
+ 	case CODE_LABEL:
+ 	case BARRIER:
+ 	  /* forget everything */
+ 	  bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	  break;
+ 
+ 	case INSN:
+           if (GET_CODE (PATTERN (insn)) == CLOBBER)
+             {
+ 	      if (GET_CODE (SET_DEST (PATTERN (insn))) == REG)
+ 		{
+ 		  rinfo[ REGNO (SET_DEST (PATTERN (insn)))].insn_set = NULL;
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].insn_set
+ 			  && reg_overlap_mentioned_p (SET_DEST (PATTERN (insn)), 
+ 			        SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			)
+ 			{	/* current value of reg dest overwritten */
+ 			  rinfo[i].insn_set = NULL;
+ 			}
+ 		    }
+ 		}
+             }
+ 	  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	    {
+ 	      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ 		{
+ 		  rtx cur_rtx;
+ 		  cur_rtx = XVECEXP (PATTERN (insn), 0, i);
+ 		  if ((GET_CODE (cur_rtx) == SET  
+ 		       || GET_CODE (cur_rtx) == CLOBBER)
+ 		      && GET_CODE (SET_DEST (cur_rtx)) == REG)
+ 		    {
+ 		      rinfo[ REGNO (SET_DEST (cur_rtx))].insn_set = NULL;
+ 		      for (i = 0; i < cur_max_reg; i++)
+ 		        {
+ 		          if (rinfo[i].insn_set
+ 			      && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
+ 			             SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			    )
+ 			    {	/* current value of reg dest overwritten */
+ 			      rinfo[i].insn_set = NULL;
+ 			    }
+ 		        }
+ 		    }
+ 		  if (!(GET_CODE (cur_rtx) == SET  
+ 		       || GET_CODE (cur_rtx) == CLOBBER
+ 		       || GET_CODE (cur_rtx) == USE))
+ 	            bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 		}
+ 	    }
+ 	  else if (GET_CODE (PATTERN (insn)) == SET)
+ 	    {
+ 	      dest = SET_DEST (PATTERN (insn));
+ 	      src = SET_SRC (PATTERN (insn));
+ 	      if (GET_CODE (src) == REG)
+ 		{
+ 		  i = REGNO (src);
+                   if (rinfo[i].insn_set
+                       && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
+                     { /* Since insn_set cannot be deleted stop optimization */
+                       rinfo[i].insn_set = NULL;
+                     }
+                 }
+ 	      else /* (GET_CODE (src) != REG) */
+ 		{
+ 	          count_reg_uses (src, regs_in_body);
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+                       if (rinfo[i].insn_set
+                           && regs_in_body[i]
+                           && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
+                         { /* Since insn_set cannot be deleted stop optimization */
+                           rinfo[i].insn_set = NULL;
+                         }
+ 		      if (reg_n_sets[i] == 1
+ 		          && regs_in_body[i]
+ 			  && rinfo[i].insn_set
+ 			  && GET_CODE (rinfo[i].insn_set) == INSN)
+ 			{	
+ 			  if (find_regno_note (insn, REG_DEAD, i))
+ 			    {
+ 			      /* copy insn_set just prior to insn */
+ 			      do_correction (i, insn, dump_file);
+ 			    }
+ 			  else
+ 			    { /* A use that is not dead - stop.  */
+                               rinfo[i].insn_set = NULL;
+ 			    }
+ 			}
+ 		    }
+ 		  bzero (regs_in_body, cur_max_reg * sizeof (int));
+ 		}
+ 	      if (GET_CODE (dest) != REG)
+ 		{
+ 		  count_reg_uses (dest, regs_in_body);
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+                       if (rinfo[i].insn_set
+                           && regs_in_body[i]
+                           && BLOCK_NUM (insn) == BLOCK_NUM (rinfo[i].insn_set))
+                         { /* Since insn_set cannot be deleted stop optimization */
+                           rinfo[i].insn_set = NULL;
+                         }
+ 		      if (reg_n_sets[i] == 1
+ 		          && !rinfo[i].copied_for_src
+ 		          && regs_in_body[i]
+ 			  && rinfo[i].insn_set
+ 			  && GET_CODE (rinfo[i].insn_set) == INSN)
+ 			{
+ 			  if (find_regno_note (insn, REG_DEAD, i))
+ 			    {
+ 			      /* copy insn_set just prior to insn */
+ 			      do_correction (i, insn, dump_file);
+ 			    }
+ 			  else
+ 			    { /* A use that is not dead - stop.  */
+                               rinfo[i].insn_set = NULL;
+ 			    }
+ 
+ 			}
+ 		    }
+ 		  bzero (regs_in_body, cur_max_reg * sizeof (int));
+ 		}
+ 	      for (i = 0; i < cur_max_reg; i++)
+ 		{
+ 		  rinfo[i].copied_for_src = 0;
+ 		}
+ 	      if (GET_CODE (dest) == REG)
+ 		{
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].insn_set
+ 			  && reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			)
+ 			{	/* current value of reg dest overwritten */
+ 			  rinfo[i].insn_set = NULL;
+ 			}
+ 		    }
+ 		  if (reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (insn))))
+ 		    {
+ 		      rinfo[REGNO (dest)].insn_set = NULL;
+ 		    }
+ 		  else
+ 		    {
+ 		      if ((GET_CODE (SET_SRC (PATTERN (insn))) == ASHIFT
+ 		           && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
+ 			   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 			  || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
+ 		              && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
+ 			      && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF)
+ 			  || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
+ 			      && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT
+ 			      && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG
+ 			      && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == CONST_INT
+ 			      && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 			  || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
+ 		              && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG
+ 			      && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 			)
+ 			{	/* these may be combinable */
+ 			  if (REG_NOTES (insn) == NULL)
+ 			    { /* Don't want to mess around with
+ 			         the REG_NOTES.  */
+ 			      rinfo[REGNO (dest)].insn_set = insn;
+ 			    }
+ 			}
+ 		      else
+ 			{
+ 			  rinfo[REGNO (dest)].insn_set = NULL;
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	  else if (GET_CODE (PATTERN (insn)) == USE)
+ 	    ; /* nothing */
+ 	  else 
+ 	    {
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  /* A register that dies cannot be used further in a substitution.  */
+           for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ 	    if (REG_NOTE_KIND (note) == REG_DEAD
+ 		&& GET_CODE (XEXP (note, 0)) == REG)
+ 	      {
+ 		for (i = 0; i < cur_max_reg; i++)
+ 		  {
+ 		    if (rinfo[i].insn_set
+ 			&& reg_overlap_mentioned_p (XEXP (note, 0), 
+ 			      SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 		       )
+ 		      {	
+ 			  rinfo[i].insn_set = NULL;
+ 	              }
+ 		  }    
+ 	      }
+ 
+ 	  break;
+ 
+ 	case JUMP_INSN:
+ 	case NOTE:
+ 	  break;
+ 
+ 	default:
+ 	  bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	  break;
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   for (i = 0; i < cur_max_reg; i++)
+     reg_n_sets[i] += my_reg_n_sets[i];
+ }
+ 
+ /*
+   Increment the reg_n_uses element for each register mentioned in body
+   and for each time it is mentioned
+ */
+ static void
+ count_reg_uses (body, where_to_count)
+      rtx body;
+      int *where_to_count;
+ {
+   int i, j, ret_val = 0;
+   char *fmt;
+   register RTX_CODE code = GET_CODE (body);
+ 
+   if (code == CLOBBER)
+     return;
+   else if (code == REG)
+     where_to_count[REGNO (body)]++;
+   else if (code == SET)
+     {
+       if (GET_CODE (SET_DEST (body)) != REG)
+ 	{
+ 	  count_reg_uses (SET_DEST (body), where_to_count);
+ 	}
+       count_reg_uses (SET_SRC (body), where_to_count);
+     }
+   else
+     {
+       fmt = GET_RTX_FORMAT (code);
+       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ 	if (fmt[i] == 'e')
+ 	  count_reg_uses (XEXP (body, i), where_to_count);
+ 	else if (fmt[i] == 'E' || fmt[i] == 'V')
+ 	  {
+ 	    for (j = 0; j < XVECLEN (body, i); j++)
+ 	      count_reg_uses (XVECEXP (body, i, j), where_to_count);
+ 	  }
+     }
+ }
+ 
+ /*
+    Copy the insn that sets regnum to just before insn.
+    If that insn has been copied to in front of each of
+    it's uses then delete it
+ */
+ static void
+ do_correction (regnum, insn, dump_file)
+      int regnum;
+      rtx insn;
+      FILE * dump_file;
+ {
+   rtx insn_set;
+   int i;
+   
+   insn_set
+     = rinfo[regnum].insn_set;
+   if (BLOCK_NUM (insn) == BLOCK_NUM (insn_set))
+     { /* Since insn_set cannot be deleted stop optimization */
+       rinfo[regnum].insn_set = NULL;
+       return;
+     }
+   emit_insn_before (
+ 		     copy_rtx (PATTERN (insn_set)),
+ 		     insn);
+    
+   if (REG_NOTES (insn_set))
+     {
+       REG_NOTES (PREV_INSN (insn))
+ 	= copy_rtx (REG_NOTES (insn_set));
+     }
+   LOG_LINKS (insn)
+     = gen_rtx (INSN_LIST, VOIDmode, PREV_INSN (insn),
+ 	       LOG_LINKS (insn));
+   if (find_insn_list (insn_set,
+ 		      LOG_LINKS (insn)))
+     remove_dependence (insn, insn_set);
+   rinfo[regnum].num_uses_copied += regs_in_body[regnum];
+   my_reg_n_sets[regnum]++;
+   if (dump_file)
+     {
+       fprintf (dump_file,
+ 	       " copy insn %d to before insn %d\n",
+ 	       INSN_UID (insn_set), INSN_UID (insn));
+     }
+   if (rinfo[regnum].num_uses_copied == reg_n_uses[regnum])
+     {	/* insn_set is no longer relevant - delete it */
+       rinfo[regnum].insn_set = NULL;
+       PUT_CODE (insn_set, NOTE);
+       NOTE_LINE_NUMBER (insn_set) = NOTE_INSN_DELETED;
+       NOTE_SOURCE_FILE (insn_set) = 0;
+       if (dump_file)
+ 	{
+ 	  fprintf (dump_file,
+ 		   " delete insn %d \n",
+ 		   INSN_UID (insn_set));
+ 	}
+       reg_n_sets[regnum]--;
+     }
+   /* If insn was a basic block head then now the copy is
+      the basic block head.  */
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       if (basic_block_head[i] == insn)
+         {
+           basic_block_head[i] = PREV_INSN (insn);
+           break;
+         }
+     }
+   
+ }
+ 
+ /* intel2 */
+ /* Call flow_analysis without changing insns, and if save_pseudo is set, saves
+    the basic_block_live_at_start information, concerning the pseudo registers,
+    and restores it after flow_analysis. */
+ 
+ void
+ hard_reg_flow_analysis (f, file, save_pseudo)
+      rtx f;
+      FILE *file;
+      int save_pseudo;
+ {
+   int limit;
+   register int block, regno;
+ 
+   /* Element N is a regset describing the registers live
+      at the start of basic block N, as was saved before the call to
+      flow_analysis. We use it to restore the contents of the pseudo registers,
+      needed by other phases. */
+     
+   regset *basic_block_live_at_start_saved;
+     
+ #if 0
+   register int j;
+ #endif
+ 
+   if (save_pseudo)
+     {
+       int regset_size = ((max_regno + REGSET_ELT_BITS - 1) / REGSET_ELT_BITS);
+       int regset_bytes = regset_size * sizeof (*(regset)0);
+       basic_block_live_at_start_saved =
+   			   (regset *) alloca (n_basic_blocks * sizeof (regset));
+       /* copy basic_block_live_at_start to basic_block_live_at_start_saved */
+       for (block = 0; block < n_basic_blocks; block++)
+         {
+           basic_block_live_at_start_saved[block] = (regset) alloca (regset_bytes);
+           bcopy (basic_block_live_at_start[block],
+     	         basic_block_live_at_start_saved[block],
+     	         regset_bytes);
+         }
+ 
+ #if 0
+       /* Check if copy is o.k. */
+       if (file)
+         {
+           fprintf (file, "Pseudo registers live at start:\n");
+ 
+           for (block = 0; block < n_basic_blocks; block++)
+ 	    {
+ 	      fprintf (file, "\nBlock no. %d original:", block);
+ 
+ 	      for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
+ 	        {
+ 	          register int offset = regno / REGSET_ELT_BITS;
+ 	          register REGSET_ELT_TYPE bit
+ 	      		     = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+ 	          if ((basic_block_live_at_start_saved[block][offset] & bit)
+ 	              ^ (basic_block_live_at_start[block][offset] & bit))
+ 	            {
+ 		      fprintf (file, "\nERROR: differnt values in regsets!\n");
+ 		      fprintf (file,
+ 			       "original: %d, saved: %d\n",
+ 			       basic_block_live_at_start[block][offset],
+ 			       basic_block_live_at_start_saved[block][offset]);
+ 	              abort ();
+ 	            }
+ 	          if (basic_block_live_at_start[block][offset] & bit)
+ 	            fprintf (file, " %d", regno);
+ 	        }
+ 	      fprintf (file, "\nSaved:");
+ 	      for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
+ 	        {
+ 	          register int offset = regno / REGSET_ELT_BITS;
+ 	          register REGSET_ELT_TYPE bit
+ 	      		     = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+ 
+ 	          if (basic_block_live_at_start_saved[block][offset] & bit)
+ 	            fprintf (file, " %d", regno);
+ 	        }
+ 	      fprintf (file, "\n");
+             }  /* for (block = 0; block < n_basic_blocks; block++) */
+         }  /* if (file) */
+ #endif
+     }  /* if (save_pseudo) */
+ 
+   limit = max_reg_num ();
+ 
+   /* Do control and data flow analysis, and write the results to the dump
+    * file, if dump wanted.
+    */
+   flow_analysis (f, limit, file, 0 /* do not allow a change to the insns */ );
+ 
+   if (save_pseudo)
+     {
+       /* restore the contents of pseudo registers if basic_block_live_at_start */
+       for (block = 0; block < n_basic_blocks; block++)
+         {
+           for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
+             {
+               register int offset = regno / REGSET_ELT_BITS;
+               register REGSET_ELT_TYPE bit
+ 	      		     = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+ 
+ 	      if (basic_block_live_at_start_saved[block][offset] & bit)
+ 	        basic_block_live_at_start[block][offset] |= bit;
+ 	      else
+ 	        basic_block_live_at_start[block][offset] &= ~bit;
+             }
+         }
+ 
+ #if 0
+       /* Check if copy is o.k. */
+       if (file)
+         {
+           fprintf (file, "Pseudo registers live at start - restored :\n");
+ 
+           for (block = 0; block < n_basic_blocks; block++)
+ 	    {
+ 	      fprintf (file, "Block no. %d:", block);
+ 	      for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
+ 	        {
+ 	          register int offset = regno / REGSET_ELT_BITS;
+ 	          register REGSET_ELT_TYPE bit
+ 	      		     = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+ 	          if (basic_block_live_at_start[block][offset] & bit)
+ 	            fprintf (file, " %d", regno);
+ 	        }
+ 	      fprintf (file, "\n");
+             }
+         }
+ #endif
+     }  /* if (save_pseudo) */
+ }  /* hard_reg_flow_analysis (f, file, save_pseudo) */
diff -rNci gcc-2.7.2/fold-const.c gcc-2.7.2p/fold-const.c
*** gcc-2.7.2/fold-const.c	Fri Sep 15 22:26:12 1995
--- gcc-2.7.2p/fold-const.c	Tue Jan 23 09:35:24 1996
***************
*** 3645,3651 ****
  	return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        else if (! FLOAT_TYPE_P (type))
  	{
! 	  if (integer_zerop (arg1))
  	    return non_lvalue (convert (type, arg0));
  
  	  /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
--- 3645,3656 ----
  	return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        else if (! FLOAT_TYPE_P (type))
  	{
! 	  if (integer_zerop (arg1)
! 	      /* intel1 if it is pointer_type then removing the + 0 here
! 	         will cause references to array[0] not to be marked
! 	         as MEM_IN_STRUCT_P.  So just leave the + 0 here - it
! 	         will be removed when the tree is made into rtl anyway.  */
! 	      && TREE_CODE (TREE_TYPE (arg0)) != POINTER_TYPE)
  	    return non_lvalue (convert (type, arg0));
  
  	  /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
***************
*** 4010,4015 ****
--- 4015,4045 ----
      case FLOOR_DIV_EXPR:
      case CEIL_DIV_EXPR:
      case EXACT_DIV_EXPR:
+    /* intel1 - implemet x/C where c is floating point and a power of two
+               as x*(1/C)
+    */
+ #ifndef REAL_IS_NOT_DOUBLE
+       if (HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
+          && TREE_CODE (t) == RDIV_EXPR
+          && TREE_CODE (TREE_TYPE (t)) == REAL_TYPE
+          && TYPE_NAME (TREE_TYPE (t))
+          && TREE_CODE (TYPE_NAME TREE_TYPE (t)) == TYPE_DECL
+          && TREE_CODE (TREE_OPERAND (t,  1)) == REAL_CST
+          && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1))) == REAL_TYPE
+          && TYPE_NAME (TREE_TYPE (TREE_OPERAND (t, 1)))
+          && TREE_CODE (TYPE_NAME (TREE_TYPE (TREE_OPERAND(t, 1))))== TYPE_DE CL
+          && TREE_REAL_CST (TREE_OPERAND (t, 1)) >= 2.0
+          && TREE_REAL_CST (TREE_OPERAND (t, 1))
+           ==(double)(REAL_VALUE_UNSIGNED_FIX(TREE_REAL_CST(TREE_OPERAND(t, 1))))
+           &&exact_log2(REAL_VALUE_UNSIGNED_FIX(TREE_REAL_CST(TREE_OPERAND(t,1)))) != -1
+          )
+         {
+           TREE_SET_CODE (t, MULT_EXPR);
+           code = TREE_CODE (t);
+           TREE_REAL_CST (TREE_OPERAND (t, 1))
+             = 1.0 / TREE_REAL_CST (TREE_OPERAND (t, 1));
+         }
+ #endif
        if (integer_onep (arg1))
  	return non_lvalue (convert (type, arg0));
        if (integer_zerop (arg1))
diff -rNci gcc-2.7.2/jump.c gcc-2.7.2p/jump.c
*** gcc-2.7.2/jump.c	Thu Oct 26 11:27:39 1995
--- gcc-2.7.2p/jump.c	Tue Jan 23 09:35:27 1996
***************
*** 1920,1926 ****
  
  	      /* First, cross jumping of conditional jumps:  */
  
! 	      if (cross_jump && condjump_p (insn))
  		{
  		  rtx newjpos, newlpos;
  		  rtx x = prev_real_insn (JUMP_LABEL (insn));
--- 1920,1935 ----
  
  	      /* First, cross jumping of conditional jumps:  */
  
! 	      if (cross_jump && condjump_p (insn)
! 	      /* intel1 */
! #ifdef NO_CROSS_JUMP_ON_LOOP_ENTRY
!                   && !(GET_CODE (NEXT_INSN(insn)) == NOTE
! 	               && 
! 	               (NOTE_LINE_NUMBER (NEXT_INSN(insn)) == NOTE_INSN_LOOP_BEG 
! 	                || NOTE_LINE_NUMBER (NEXT_INSN(insn)) == NOTE_INSN_LOOP_END)
! 	              )
! #endif
! 	         )
  		{
  		  rtx newjpos, newlpos;
  		  rtx x = prev_real_insn (JUMP_LABEL (insn));
diff -rNci gcc-2.7.2/loop.c gcc-2.7.2p/loop.c
*** gcc-2.7.2/loop.c	Tue Oct  3 16:17:16 1995
--- gcc-2.7.2p/loop.c	Tue Jan 23 09:25:29 1996
***************
*** 39,44 ****
--- 39,45 ----
  #include "rtl.h"
  #include "obstack.h"
  #include "expr.h"
+ #include "basic-block.h" /* intel1 */
  #include "insn-config.h"
  #include "insn-flags.h"
  #include "regs.h"
***************
*** 46,51 ****
--- 47,53 ----
  #include "recog.h"
  #include "flags.h"
  #include "real.h"
+ #include "reload.h" /* intel1 */
  #include "loop.h"
  
  /* Vector mapping INSN_UIDs to luids.
***************
*** 97,107 ****
  
  rtx *loop_number_exit_labels;
  
- /* Indexed by loop number, counts the number of LABEL_REFs on
-    loop_number_exit_labels for this loop and all loops nested inside it.  */
- 
- int *loop_number_exit_count;
- 
  /* Holds the number of loop iterations.  It is zero if the number could not be
     calculated.  Must be unsigned since the number of iterations can
     be as high as 2^wordsize-1.  For loops with a wider iterator, this number
--- 99,104 ----
***************
*** 191,196 ****
--- 188,196 ----
  
  static struct obstack temp_obstack;
  
+ /* intel1 */
+ extern struct obstack momentary_obstack;
+ 
  /* This is where the pointer to the obstack being used for RTL is stored.  */
  
  extern struct obstack *rtl_obstack;
***************
*** 286,291 ****
--- 286,349 ----
  static int last_use_this_basic_block ();
  static void record_initial ();
  static void update_reg_last_use ();
+ /* intel1 */
+ static int compare_elimination ();
+ static attempt_new_rtx ();
+ static rtx make_new_use ();
+ static int possible_compare_elimination ();
+ static void find_regs_mentioned ();
+ static void use_regs_source ();
+ static rtx replace_mems ();
+ static void replace_reg  ();
+ static int two_to_power ();
+ static int jumps_back_in_loop ();
+ static loop_copy_propogate ();
+ static do_replace ();
+ static rtx subst_cands ();
+ static try_unroll_propogation ();
+ static rtx unroll_subst_cands ();
+ static unroll_consistancy_maintained ();
+ static int do_reduce_index ();
+ static loop_spl ();
+ void loop_after_global ();
+ static int spill_invariant_p ();
+ static void move_spills_out ();
+ static void move_spill_movables ();
+ static rtx subst_stack_slot ();
+ static int check_if_jumps_out_of_loop ();
+ static void mark_regs_alive_at_exit ();
+ static void verify_spill_candidates ();
+ static void mark_spill_candidates ();
+ static void spill_handle_regs_mentioned ();
+ static int is_updated_by_const ();
+ static int is_updated_by_const_or_reg ();
+ static void peep_init_info ();
+ static void spill_peep_insn ();
+ void update_stack_offset ();
+ static void replace_spill_slots ();
+ static rtx replace_linked_regs ();
+ static void mark_regs_live_outside ();
+ static void mark_regs_mentioned ();
+ static int loop_contains_loop ();
+ static void push_load_into_loop ();
+ static int spill_slot_unused_between ();
+ static int spill_slot_mentioned ();
+ void init_undo_buf ();
+ void subst_in_insn ();
+ static void inner_subst_in_insn ();
+ void loop_undo_all ();
+ static void update_last_reloads ();
+ static void sign_extension_reduction ();
+ static void validate_all_references ();
+ static void lift_stores ();
+ static void mark_mem_refs ();
+ static void insert_mem_ref ();
+ static void opt_reg_use_copy ();
+ int doing_spl = 0;
+ int doing_loop_after_global = 0;
+ static char * reg_live_outside_loop;
+ static int cur_stack_offset = 0;
+ 
  
  /* Relative gain of eliminating various kinds of operations.  */
  int add_cost;
***************
*** 293,298 ****
--- 351,360 ----
  int shift_cost;
  int mult_cost;
  #endif
+ /* intel1 maximum # of insns in loop for which compare elimination */
+ #ifndef MAX_CMP_ELIM
+ #define MAX_CMP_ELIM 100
+ #endif
  
  /* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
     copy the value of the strength reduced giv to its original register.  */
***************
*** 341,346 ****
--- 403,414 ----
  
    max_reg_before_loop = max_reg_num ();
  
+   /* intel1 */
+ #ifdef SAVE_ON_REGS
+   if (!flag_all_mem_givs && flag_opt_reg_use)
+     reg_live_outside_loop = (char *) alloca(max_reg_before_loop);
+ #endif
+ 
    moved_once = (char *) alloca (max_reg_before_loop);
    bzero (moved_once, max_reg_before_loop);
  
***************
*** 358,364 ****
  
    /* Don't waste time if no loops.  */
    if (max_loop_num == 0)
!     return;
  
    /* Get size to use for tables indexed by uids.
       Leave some space for labels allocated by find_and_verify_loops.  */
--- 426,442 ----
  
    /* Don't waste time if no loops.  */
    if (max_loop_num == 0)
!     {
!       /* intel1 */
! #ifdef SAVE_ON_REGS
!       if (!doing_loop_after_global && flag_opt_reg_use)
!         {
!           use_regs_source (f, NULL, 0);
!           opt_reg_use_copy (f);
!         }
! #endif
!       return;
!     }
  
    /* Get size to use for tables indexed by uids.
       Leave some space for labels allocated by find_and_verify_loops.  */
***************
*** 377,383 ****
    loop_outer_loop = (int *) alloca (max_loop_num * sizeof (int));
    loop_invalid = (char *) alloca (max_loop_num * sizeof (char));
    loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
-   loop_number_exit_count = (int *) alloca (max_loop_num * sizeof (int));
  
    /* Find and process each loop.
       First, find them, and record them in order of their beginnings.  */
--- 455,460 ----
***************
*** 386,392 ****
    /* Now find all register lifetimes.  This must be done after
       find_and_verify_loops, because it might reorder the insns in the
       function.  */
!   reg_scan (f, max_reg_num (), 1);
  
    /* See if we went too far.  */
    if (get_max_uid () > max_uid_for_loop)
--- 463,470 ----
    /* Now find all register lifetimes.  This must be done after
       find_and_verify_loops, because it might reorder the insns in the
       function.  */
!   /* intel1  Last paramater of reg_scan used to be 1.  */
!   reg_scan (f, max_reg_num (), !doing_loop_after_global);
  
    /* See if we went too far.  */
    if (get_max_uid () > max_uid_for_loop)
***************
*** 437,442 ****
--- 515,557 ----
        scan_loop (loop_number_loop_starts[i], loop_number_loop_ends[i],
  		 max_reg_num ());
  
+   /* intel1 */
+   if (flag_strength_reduce && flag_copy_prop)
+     {  
+       for (i = max_loop_num-1; i >= 0; i--)
+         {
+           if (! loop_invalid[i] && loop_number_loop_ends[i])
+             loop_copy_propogate (loop_number_loop_starts[i], loop_number_loop_ends[i]);
+         }
+     }
+   /* intel1 */
+   if ((flag_lift_stores || flag_runtime_lift_stores) 
+       && !doing_loop_after_global)
+     {  
+       for (i = max_loop_num-1; i >= 0; i--)
+         {
+           if (! loop_invalid[i] && loop_number_loop_ends[i])
+                lift_stores (loop_number_loop_starts[i], loop_number_loop_ends[i]);
+         }
+     }
+ 
+ #ifdef SAVE_ON_REGS
+   if (!doing_loop_after_global && flag_opt_reg_use)
+     {
+       use_regs_source (f, NULL, 0); 
+       opt_reg_use_copy (f);
+     }
+ #endif
+   /* intel1 */
+ #ifdef STORE_NOT_SET_CC0
+ #ifdef STACK_REGS
+   if (flag_sftwr_pipe && !doing_loop_after_global)
+       for (i = max_loop_num-1; i >= 0; i--)
+         {
+           loop_spl (loop_number_loop_starts[i], loop_number_loop_ends[i], i, 0);
+         }
+ #endif
+ #endif
    /* If debugging and unrolling loops, we must replicate the tree nodes
       corresponding to the blocks inside the loop, so that the original one
       to one mapping will remain.  */
***************
*** 493,501 ****
--- 608,636 ----
       if it was used exactly once; contains const0_rtx if it was used more
       than once.  */
    rtx *reg_single_usage = 0;
+   
    /* Nonzero if we are scanning instructions in a sub-loop.  */
    int loop_depth = 0;
  
+   /* intel1 */
+   if (doing_loop_after_global
+      && !(GET_CODE (PREV_INSN (end)) == JUMP_INSN
+      &&   GET_CODE (NEXT_INSN (loop_start)) == CODE_LABEL
+      &&   JUMP_LABEL (PREV_INSN (end)) == NEXT_INSN (loop_start)
+       )
+     )
+   {
+     return;
+   }
+ #ifdef SAVE_ON_REGS
+   if (!flag_all_mem_givs && !doing_loop_after_global
+      && !loop_contains_loop (loop_start, end) && flag_opt_reg_use)
+     {
+       bzero (reg_live_outside_loop, max_reg_before_loop);
+       mark_regs_live_outside (loop_start, end);
+     }
+ #endif
+ 
    n_times_set = (short *) alloca (nregs * sizeof (short));
    n_times_used = (short *) alloca (nregs * sizeof (short));
    may_not_optimize = (char *) alloca (nregs);
***************
*** 591,597 ****
  
    count_loop_regs_set (loop_top ? loop_top : loop_start, end,
  		       may_not_optimize, reg_single_usage, &insn_count, nregs);
! 
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      may_not_optimize[i] = 1, n_times_set[i] = 1;
    bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (short));
--- 726,733 ----
  
    count_loop_regs_set (loop_top ? loop_top : loop_start, end,
  		       may_not_optimize, reg_single_usage, &insn_count, nregs);
!   /* intel1 added if but not body */
!   if (!doing_loop_after_global)
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      may_not_optimize[i] = 1, n_times_set[i] = 1;
    bcopy ((char *) n_times_set, (char *) n_times_used, nregs * sizeof (short));
***************
*** 644,649 ****
--- 780,787 ----
  	in_libcall = 0;
  
        if (GET_CODE (p) == INSN
+           /* intel1 */
+       && (!doing_loop_after_global || GET_CODE(PATTERN(p)) == SET)
  	  && (set = single_set (p))
  	  && GET_CODE (SET_DEST (set)) == REG
  	  && ! may_not_optimize[REGNO (SET_DEST (set))])
***************
*** 695,705 ****
  	  else if (! ((! maybe_never
  		       && ! loop_reg_used_before_p (set, p, loop_start,
  						    scan_start, end))
! 		      || (! REG_USERVAR_P (SET_DEST (set))
! 			  && ! REG_LOOP_TEST_P (SET_DEST (set)))
  		      || reg_in_basic_block_p (p, SET_DEST (set))))
  	    ;
! 	  else if ((tem = invariant_p (src))
  		   && (dependencies == 0
  		       || (tem2 = invariant_p (dependencies)) != 0)
  		   && (n_times_set[REGNO (SET_DEST (set))] == 1
--- 833,851 ----
  	  else if (! ((! maybe_never
  		       && ! loop_reg_used_before_p (set, p, loop_start,
  						    scan_start, end))
! 		      ||  (!doing_loop_after_global 
! 		           && /* intel1 */!REG_USERVAR_P (SET_DEST (set))
! 		           && ! REG_LOOP_TEST_P (SET_DEST (set)))
  		      || reg_in_basic_block_p (p, SET_DEST (set))))
  	    ;
! 	  else if (((tem = invariant_p (src))
! 	             /* intel1 */ || (doing_loop_after_global 
! 	             && RTX_IS_SPILL_P (p) == 1 && spill_invariant_p (src))
! 	           )
! 	           /* intel1 */
!                     && !(doing_loop_after_global 
! 	            && call_used_regs[REGNO (SET_DEST (set))]
! 	            && loop_has_call)
  		   && (dependencies == 0
  		       || (tem2 = invariant_p (dependencies)) != 0)
  		   && (n_times_set[REGNO (SET_DEST (set))] == 1
***************
*** 749,754 ****
--- 895,901 ----
  		     might span a call.  */
  		  && ! modified_between_p (SET_SRC (set), p,
  					   reg_single_usage[regno])
+           && !doing_loop_after_global /* intel1 */
  		  && no_labels_between_p (p, reg_single_usage[regno])
  		  && validate_replace_rtx (SET_DEST (set), SET_SRC (set),
  					   reg_single_usage[regno]))
***************
*** 966,977 ****
--- 1113,1137 ----
    move_movables (movables, threshold,
  		 insn_count, loop_start, end, nregs);
  
+   /* intel1 */
+   if (doing_loop_after_global && !loop_has_call)
+     {
+       move_spills_out(loop_start, end, nregs);
+     }
    /* Now candidates that still are negative are those not moved.
       Change n_times_set to indicate that those are not actually invariant.  */
    for (i = 0; i < nregs; i++)
      if (n_times_set[i] < 0)
        n_times_set[i] = n_times_used[i];
  
+   /*intel1 */
+ #ifdef SAVE_ON_REGS
+    if (!doing_loop_after_global && flag_opt_reg_use)
+    {
+      use_regs_source(loop_start, end, 1); 
+    }
+ #endif
+ 
    if (flag_strength_reduce)
      strength_reduce (scan_start, end, loop_top,
  		     insn_count, loop_start, end);
***************
*** 1257,1263 ****
  	      /* A reg used for zero-extending mustn't be eliminated.  */
  	      && !m1->partial
  	      && (matched_regs[m1->regno]
! 		  ||
  		  (
  		   /* Can combine regs with different modes loaded from the
  		      same constant only if the modes are the same or
--- 1417,1423 ----
  	      /* A reg used for zero-extending mustn't be eliminated.  */
  	      && !m1->partial
  	      && (matched_regs[m1->regno]
! 		  || 
  		  (
  		   /* Can combine regs with different modes loaded from the
  		      same constant only if the modes are the same or
***************
*** 1534,1539 ****
--- 1694,1706 ----
       rtx end;
       int nregs;
  {
+ /* intel1 */
+ #ifdef SAVE_ON_REGS
+   rtx sinsn,last_sym;
+   int num_sym_adds;
+ #endif
+   /* intel1 */
+   int *insns_deleted;
    rtx new_start = 0;
    register struct movable *m;
    register rtx p;
***************
*** 1548,1553 ****
--- 1715,1760 ----
  
    num_movables = 0;
  
+   /* intel1 */
+   num_movables = 0;
+ 
+ /* intel1 Any insn moved out of loop must be deleted from the log_links
+           of all other insns in the loop.
+ */
+   if (doing_loop_after_global)
+     {
+         insns_deleted = (int *) alloca ((max_uid_for_loop+1) * sizeof (int));
+         bzero(insns_deleted,(max_uid_for_loop+1) * sizeof (int));
+     }
+ /* intel1 */
+ #ifdef SAVE_ON_REGS
+   num_sym_adds=0;
+   last_sym = NULL;
+   for (sinsn=loop_start;flag_opt_reg_use && (sinsn!=end && num_sym_adds < 2);
+         sinsn=NEXT_INSN (sinsn))
+      {
+         if (GET_CODE (sinsn) == INSN
+            && GET_CODE (PATTERN (sinsn)) == SET
+            && GET_CODE (SET_DEST (PATTERN (sinsn))) == REG
+            && GET_CODE (SET_SRC (PATTERN (sinsn))) == PLUS
+            && GET_CODE (XEXP (SET_SRC (PATTERN (sinsn)), 0)) == REG
+            && GET_CODE (XEXP (SET_SRC (PATTERN (sinsn)), 1)) == SYMBOL_REF)
+       {
+         if (last_sym)
+       {
+         if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (sinsn)), 1),
+                         last_sym))
+           {
+             num_sym_adds++;
+           }
+       }
+         else
+       {
+         last_sym = XEXP (SET_SRC (PATTERN (sinsn)), 1);
+       }
+       }
+     }
+ #endif /* SAVE_ON_REGS */
    for (m = movables; m; m = m->next)
      {
        /* Describe this movable insn.  */
***************
*** 1626,1632 ****
  
  	  /* It is also desirable to move if it can be moved at no
  	     extra cost because something else was already moved.  */
! 
  	  if (already_moved[regno]
  	      || (threshold * savings * m->lifetime) >= insn_count
  	      || (m->forces && m->forces->done
--- 1833,1862 ----
  
  	  /* It is also desirable to move if it can be moved at no
  	     extra cost because something else was already moved.  */
! #ifdef SAVE_ON_REGS
!   	  /* intel1 if the insn is regx <- regy + symbol_ref then don't move
!   	     if there is more than one.  
!   	  */
!   	  if (flag_opt_reg_use
!   	     && num_sym_adds > 1 
!   	     && GET_CODE (PATTERN (m->insn)) == SET 
!   	     && GET_CODE (SET_DEST (PATTERN (m->insn))) == REG 
!   	     && GET_CODE (SET_SRC (PATTERN (m->insn))) == PLUS 
!   	     && GET_CODE (XEXP (SET_SRC (PATTERN (m->insn)), 0)) == REG 
!   	     && GET_CODE (XEXP (SET_SRC (PATTERN (m->insn)), 1)) == SYMBOL_REF)
! 	    {
! 	      savings = 0;
! 	    } 
! #endif  	     
! /* intel1 */
! #ifdef STACK_REGS
! #ifdef IS_STACK_MODE
!           if (IS_STACK_MODE (DFmode)
!              && GET_CODE (PATTERN (m->insn)) == SET 
!              && GET_CODE (SET_SRC (PATTERN (m->insn))) == CONST_DOUBLE)
!             savings = 0; /* not worthwhile */
! #endif
! #endif
  	  if (already_moved[regno]
  	      || (threshold * savings * m->lifetime) >= insn_count
  	      || (m->forces && m->forces->done
***************
*** 1659,1669 ****
--- 1889,1912 ----
  		  regs_may_share = gen_rtx (EXPR_LIST, VOIDmode, r1,
  					    gen_rtx (EXPR_LIST, VOIDmode, r2,
  						     regs_may_share));
+                   /* intel1 */
+                   if (doing_loop_after_global 
+                      && INSN_UID (m->insn) <= max_uid_for_loop)
+                     {
+                       insns_deleted[INSN_UID (m->insn)] = 1;
+                     }
  		  delete_insn (m->insn);
  
  		  if (new_start == 0)
  		    new_start = i1;
  
+                   /* intel1 */
+                   if (doing_loop_after_global)
+                     {
+                       RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
+                       SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
+                     }
+                     
  		  if (loop_dump_stream)
  		    fprintf (loop_dump_stream, " moved to %d", INSN_UID (i1));
  		}
***************
*** 1690,1697 ****
  			{
  			  temp = XEXP (temp, 0);
  			  while (temp != p)
! 			    temp = delete_insn (temp);
  			}
  
  		      p = delete_insn (p);
  		      while (p && GET_CODE (p) == NOTE)
--- 1933,1954 ----
  			{
  			  temp = XEXP (temp, 0);
  			  while (temp != p)
!               {
!                   /* intel1 */
!                   if (doing_loop_after_global
!                       && INSN_UID( temp) <= max_uid_for_loop)
!                   {
!                        insns_deleted[INSN_UID( temp)] = 1;
!                   }
!                 temp = delete_insn (temp);
!               }
  			}
+                /* intel1 */
+              if (doing_loop_after_global
+                 && INSN_UID( p) <= max_uid_for_loop)
+              {
+                  insns_deleted[INSN_UID( p)] = 1;
+               }
  
  		      p = delete_insn (p);
  		      while (p && GET_CODE (p) == NOTE)
***************
*** 1712,1717 ****
--- 1969,1981 ----
  				 m->is_equiv ? REG_EQUIV : REG_EQUAL,
  				 m->set_src, REG_NOTES (i1));
  
+                   /* intel1 */
+                   if (doing_loop_after_global)
+                     {
+                       RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
+                       SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
+                     }
+ 
  		  if (loop_dump_stream)
  		    fprintf (loop_dump_stream, " moved to %d", INSN_UID (i1));
  
***************
*** 1813,1818 ****
--- 2077,2088 ----
  			      if (temp == fn_address_insn)
  				fn_address_insn = i1;
  			      REG_NOTES (i1) = REG_NOTES (temp);
+                               /* intel1 */
+                               if (doing_loop_after_global 
+                                  && INSN_UID (temp) <= max_uid_for_loop)
+                                 {
+                                   insns_deleted[INSN_UID (temp)] = 1;
+                                 }
  			      delete_insn (temp);
  			    }
  			}
***************
*** 1868,1873 ****
--- 2138,2150 ----
  		      if (new_start == 0)
  			new_start = i1;
  
+                       /* intel1 */
+                       if (doing_loop_after_global)
+                         {
+                           RTX_IS_SPILL_P (i1) = RTX_IS_SPILL_P (m->insn);
+                           SPILL_PSEUDO (i1) = SPILL_PSEUDO (m->insn);
+                         }
+                         
  		      if (loop_dump_stream)
  			fprintf (loop_dump_stream, " moved to %d",
  				 INSN_UID (i1));
***************
*** 1895,1900 ****
--- 2172,2183 ----
  			  XEXP (temp, 0) = i1;
  			}
  
+                       /* intel1 */
+                       if (doing_loop_after_global 
+                          && INSN_UID (p) <= max_uid_for_loop)
+                         {
+                           insns_deleted[INSN_UID (p)] = 1;
+                         }
  		      delete_insn (p);
  		      do p = NEXT_INSN (p);
  		      while (p && GET_CODE (p) == NOTE);
***************
*** 1959,1966 ****
  			{
  			  for (temp = XEXP (temp, 0); temp != m1->insn;
  			       temp = NEXT_INSN (temp))
! 			    delete_insn (temp);
  			}
  		      delete_insn (m1->insn);
  
  		      /* Any other movable that loads the same register
--- 2242,2263 ----
  			{
  			  for (temp = XEXP (temp, 0); temp != m1->insn;
  			       temp = NEXT_INSN (temp))
! 			    {
!                               /* intel1 */
!                               if (doing_loop_after_global 
!                                  && INSN_UID (temp) <= max_uid_for_loop)
!                                 {
!                                   insns_deleted[INSN_UID (temp)] = 1;
!                                 }
! 			      delete_insn (temp);
! 			    }
  			}
+                       /* intel1 */
+                       if (doing_loop_after_global 
+                          && INSN_UID (m1->insn) <= max_uid_for_loop)
+                         {
+                           insns_deleted[INSN_UID (m1->insn)] = 1;
+                         }
  		      delete_insn (m1->insn);
  
  		      /* Any other movable that loads the same register
***************
*** 1996,2001 ****
--- 2293,2326 ----
  	replace_regs (REG_NOTES (p), reg_map, nregs, 0);
  	INSN_CODE (p) = -1;
        }
+   /* intel1 */
+   /* remove all deleted insns from the log_links of any insn in which
+      they appear */
+   if (doing_loop_after_global)
+     {
+         int i;
+         rtx rn,prev,link;
+ 
+         for (rn=loop_start; rn!=end; rn=NEXT_INSN (rn))
+           {
+               if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
+ 	               || GET_CODE (rn) == CALL_INSN) && LOG_LINKS(rn))
+                 {
+                     for (prev = 0, link = LOG_LINKS (rn); link;
+                          prev = link, link = XEXP (link, 1))
+                       {
+                           if (insns_deleted[INSN_UID(XEXP (link, 0))])
+ 	                    {
+ 	                      if (prev)
+ 	                        XEXP (prev, 1) = XEXP (link, 1);
+ 	                      else
+ 	                        LOG_LINKS (rn) = XEXP (link, 1);
+ 	                    }
+                       }
+ 
+                 }
+           }
+     }
  }
  
  #if 0
***************
*** 2246,2252 ****
  	    loop_outer_loop[next_loop] = current_loop;
  	    loop_invalid[next_loop] = 0;
  	    loop_number_exit_labels[next_loop] = 0;
- 	    loop_number_exit_count[next_loop] = 0;
  	    current_loop = next_loop;
  	    break;
  
--- 2571,2576 ----
***************
*** 2278,2283 ****
--- 2602,2610 ----
        uid_loop_num[INSN_UID (insn)] = current_loop;
      }
  
+ 		    /* This loop will be continued with NEXT_INSN (insn).  */
+ 		    insn = PREV_INSN (insn);
+ 
    /* Any loop containing a label used in an initializer must be invalidated,
       because it can be jumped into from anywhere.  */
  
***************
*** 2291,2296 ****
--- 2618,2634 ----
  	loop_invalid[loop_num] = 1;
      }
  
+ 
+ #if HAVE_movstricthi
+   if (flag_sign_extension_elim)
+     {
+       int i;
+       for (i = max_loop_num-1; i >= 0; i--)
+         if (! loop_invalid[i] && loop_number_loop_ends[i])
+           sign_extension_reduction (loop_number_loop_starts[i],
+                                     loop_number_loop_ends [i]);
+     }
+ #endif
    /* Now scan all insn's in the function.  If any JUMP_INSN branches into a
       loop that it is not contained within, that loop is marked invalid.
       If any INSN or CALL_INSN uses a label's address, then the loop containing
***************
*** 2304,2314 ****
       label in our loop and will simplify processing by both us and a
       possible second cse pass.  */
  
    for (insn = f; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
        {
  	int this_loop_num = uid_loop_num[INSN_UID (insn)];
! 
  	if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  	  {
  	    rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
--- 2642,2653 ----
       label in our loop and will simplify processing by both us and a
       possible second cse pass.  */
  
+ 
    for (insn = f; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
        {
  	int this_loop_num = uid_loop_num[INSN_UID (insn)];
!         
  	if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
  	  {
  	    rtx note = find_reg_note (insn, REG_LABEL, NULL_RTX);
***************
*** 2338,2345 ****
  	  {
  	    rtx p;
  	    rtx our_next = next_real_insn (insn);
- 	    int dest_loop;
- 	    int outer_loop = -1;
  
  	    /* Go backwards until we reach the start of the loop, a label,
  	       or a JUMP_INSN.  */
--- 2677,2682 ----
***************
*** 2351,2377 ****
  		 p = PREV_INSN (p))
  	      ;
  
! 	    /* Check for the case where we have a jump to an inner nested
! 	       loop, and do not perform the optimization in that case.  */
! 
! 	    if (JUMP_LABEL (insn))
! 	      {
! 		dest_loop = uid_loop_num[INSN_UID (JUMP_LABEL (insn))];
! 		if (dest_loop != -1)
! 		  {
! 		    for (outer_loop = dest_loop; outer_loop != -1;
! 			 outer_loop = loop_outer_loop[outer_loop])
! 		      if (outer_loop == this_loop_num)
! 			break;
! 		  }
! 	      }
! 
! 	    /* Make sure that the target of P is within the current loop.  */
! 
! 	    if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
! 		&& uid_loop_num[INSN_UID (JUMP_LABEL (p))] != this_loop_num)
! 	      outer_loop = this_loop_num;
! 
  	    /* If we stopped on a JUMP_INSN to the next insn after INSN,
  	       we have a block of code to try to move.
  
--- 2688,2719 ----
  		 p = PREV_INSN (p))
  	      ;
  
! 	      /* intel1 */
!             if (flag_opt_jumps_out)
!               {
!                 /* Retarget a jump around a sequence that contains jumps out 
!                    of loop to jump out of the loop rather than jump around.  */
!                 while (!(GET_CODE (p) == JUMP_INSN
! 		        && JUMP_LABEL (p) != 0
! 		        && condjump_p (p)
! 		        && ! simplejump_p (p)
! 		        && next_real_insn (JUMP_LABEL (p)) == our_next
! 		       ) &&
! 		      !(GET_CODE (p) == JUMP_INSN 
! 		        && (JUMP_LABEL (p) == 0 
! 		         || (uid_loop_num[INSN_UID (JUMP_LABEL (p))]
! 			    == this_loop_num))
! 		       ) 
! 		      && GET_CODE (p) != CODE_LABEL 
! 		      && !(GET_CODE (p) == NOTE
! 		           && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_BEG) 
! 		      && !(GET_CODE (p) == NOTE
! 		           && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
! 		     )
!                   {
!                     p = PREV_INSN (p);
!                   }
!               }
  	    /* If we stopped on a JUMP_INSN to the next insn after INSN,
  	       we have a block of code to try to move.
  
***************
*** 2381,2388 ****
  	       of the block, invert the jump in P and point it to that label,
  	       and move the block of code to the spot we found.  */
  
! 	    if (outer_loop == -1
! 		&& GET_CODE (p) == JUMP_INSN
  		&& JUMP_LABEL (p) != 0
  		/* Just ignore jumps to labels that were never emitted.
  		   These always indicate compilation errors.  */
--- 2723,2729 ----
  	       of the block, invert the jump in P and point it to that label,
  	       and move the block of code to the spot we found.  */
  
! 	    if (GET_CODE (p) == JUMP_INSN
  		&& JUMP_LABEL (p) != 0
  		/* Just ignore jumps to labels that were never emitted.
  		   These always indicate compilation errors.  */
***************
*** 2407,2413 ****
  			&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
  		      break;
  
! 		if (loc)
  		  {
  		    rtx cond_label = JUMP_LABEL (p);
  		    rtx new_label = get_label_after (p);
--- 2748,2762 ----
  			&& uid_loop_num[INSN_UID (loc)] == target_loop_num)
  		      break;
  
! 		if (loc 
! 		     ||
! 		    /* intel1 Enable the optimization even if no barier
! 		              is found.  This requires adding a jump
! 		              around the section of code moved out - but
! 		              this can win if jumps NOT taken are preferred.  
! 		    */
! 		    (flag_opt_jumps_out 
! 		         && LABEL_NUSES (JUMP_LABEL (p)) == 1))
  		  {
  		    rtx cond_label = JUMP_LABEL (p);
  		    rtx new_label = get_label_after (p);
***************
*** 2424,2430 ****
  		       /* Include the BARRIER after INSN and copy the
  			  block after LOC.  */
  		       new_label = squeeze_notes (new_label, NEXT_INSN (insn));
! 		       reorder_insns (new_label, NEXT_INSN (insn), loc);
  
  		       /* All those insns are now in TARGET_LOOP_NUM.  */
  		       for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
--- 2773,2784 ----
  		       /* Include the BARRIER after INSN and copy the
  			  block after LOC.  */
  		       new_label = squeeze_notes (new_label, NEXT_INSN (insn));
! 		       /* intel1 */
! 		       if (loc)
! 		         reorder_insns (new_label, NEXT_INSN (insn), loc);
! 		       else
! 		         reorder_insns (new_label, NEXT_INSN (insn), 
! 		                      PREV_INSN (target));
  
  		       /* All those insns are now in TARGET_LOOP_NUM.  */
  		       for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
***************
*** 2438,2445 ****
  			  LABEL_OUTSIDE_LOOP_P bit.  */
  		       if (JUMP_LABEL (insn))
  			 {
- 			   int loop_num;
- 
  			   for (q = 0,
  				r = loop_number_exit_labels[this_loop_num];
  				r; q = r, r = LABEL_NEXTREF (r))
--- 2792,2797 ----
***************
*** 2454,2464 ****
  				 break;
  			       }
  
- 			   for (loop_num = this_loop_num;
- 				loop_num != -1 && loop_num != target_loop_num;
- 				loop_num = loop_outer_loop[loop_num])
- 			     loop_number_exit_count[loop_num]--;
- 
  			   /* If we didn't find it, then something is wrong. */
  			   if (! r)
  			     abort ();
--- 2806,2811 ----
***************
*** 2468,2481 ****
  			  in loop_number_exit_labels, and marked as such.
  			  The easiest way to do this is to just call
  			  mark_loop_jump again for P.  */
  		       mark_loop_jump (PATTERN (p), this_loop_num);
! 
! 		       /* If INSN now jumps to the insn after it,
! 			  delete INSN.  */
! 		       if (JUMP_LABEL (insn) != 0
! 			   && (next_real_insn (JUMP_LABEL (insn))
! 			       == next_real_insn (insn)))
! 			 delete_insn (insn);
  		     }
  
  		    /* Continue the loop after where the conditional
--- 2815,2838 ----
  			  in loop_number_exit_labels, and marked as such.
  			  The easiest way to do this is to just call
  			  mark_loop_jump again for P.  */
+         
  		       mark_loop_jump (PATTERN (p), this_loop_num);
!                        /* intel1 */
!                        if (loc)
!                          {
! 		           /* If INSN now jumps to the insn after it,
! 			      delete INSN.  */
! 		           if (JUMP_LABEL (insn) != 0
! 			       && (next_real_insn (JUMP_LABEL (insn))
! 			           == next_real_insn (insn)))
! 			     delete_insn (insn);
! 			 }
! 		       else
! 		         {
! 		           /* move the jump insn to just before the new_label */
! 		           reorder_insns (insn, NEXT_INSN (insn),
! 		                          PREV_INSN (new_label));
! 		         }
  		     }
  
  		    /* Continue the loop after where the conditional
***************
*** 2484,2494 ****
  		       branch and hence needs no processing.  */
  		    insn = NEXT_INSN (cond_label);
  
! 		    if (--LABEL_NUSES (cond_label) == 0)
! 		      delete_insn (cond_label);
! 
! 		    /* This loop will be continued with NEXT_INSN (insn).  */
! 		    insn = PREV_INSN (insn);
  		  }
  	      }
  	  }
--- 2841,2856 ----
  		       branch and hence needs no processing.  */
  		    insn = NEXT_INSN (cond_label);
  
!                        /* intel1 */
!                     if (loc)
!                       {
! 		        if (--LABEL_NUSES (cond_label) == 0)
! 		          delete_insn (cond_label);
! 		       }
! 		     else
! 		       {
! 		          delete_insn (cond_label);
! 		       }
  		  }
  	      }
  	  }
***************
*** 2546,2573 ****
  	 mark this LABEL_REF so we know that this branch should predict
  	 false.  */
  
!       /* A check to make sure the label is not in an inner nested loop,
! 	 since this does not count as a loop exit.  */
!       if (dest_loop != -1)
! 	{
! 	  for (outer_loop = dest_loop; outer_loop != -1;
! 	       outer_loop = loop_outer_loop[outer_loop])
! 	    if (outer_loop == loop_num)
! 	      break;
! 	}
!       else
! 	outer_loop = -1;
! 
!       if (loop_num != -1 && outer_loop == -1)
  	{
  	  LABEL_OUTSIDE_LOOP_P (x) = 1;
  	  LABEL_NEXTREF (x) = loop_number_exit_labels[loop_num];
  	  loop_number_exit_labels[loop_num] = x;
- 
- 	  for (outer_loop = loop_num;
- 	       outer_loop != -1 && outer_loop != dest_loop;
- 	       outer_loop = loop_outer_loop[outer_loop])
- 	    loop_number_exit_count[outer_loop]++;
  	}
  
        /* If this is inside a loop, but not in the current loop or one enclosed
--- 2908,2918 ----
  	 mark this LABEL_REF so we know that this branch should predict
  	 false.  */
  
!       if (dest_loop != loop_num && loop_num != -1)
  	{
  	  LABEL_OUTSIDE_LOOP_P (x) = 1;
  	  LABEL_NEXTREF (x) = loop_number_exit_labels[loop_num];
  	  loop_number_exit_labels[loop_num] = x;
  	}
  
        /* If this is inside a loop, but not in the current loop or one enclosed
***************
*** 2593,2599 ****
--- 2938,2953 ----
  		     "\nLoop at %d ignored due to multiple entry points.\n",
  		     INSN_UID (loop_number_loop_starts[dest_loop]));
  	  
+ 	  /* intel1
+ 	     If doing loop_spl we don't care if there are multiple jumps
+ 	     to the loop entry label.  */
+ 	  if (!doing_spl 
+ 	      || NEXT_INSN (loop_number_loop_starts[dest_loop]) 
+ 	           != XEXP (x, 0))
+ 	  {
+ 	    
  	  loop_invalid[dest_loop] = 1;
+ 	  }
  	}
        return;
  
***************
*** 2624,2636 ****
  	 as a branch out of this loop, but not into any loop.  */
  
        if (loop_num != -1)
! 	{
! 	  loop_number_exit_labels[loop_num] = x;
  
- 	  for (outer_loop = loop_num; outer_loop != -1;
- 	       outer_loop = loop_outer_loop[outer_loop])
- 	    loop_number_exit_count[outer_loop]++;
- 	}
        return;
      }
  }
--- 2978,2985 ----
  	 as a branch out of this loop, but not into any loop.  */
  
        if (loop_num != -1)
! 	loop_number_exit_labels[loop_num] = x;
  
        return;
      }
  }
***************
*** 2818,2824 ****
    return 1 + conditional;
  }
  
- 
  /* Return nonzero if all the insns in the loop that set REG
     are INSN and the immediately following insns,
     and if each of those insns sets REG in an invariant way
--- 3167,3172 ----
***************
*** 3047,3052 ****
--- 3395,3416 ----
  		    may_not_move[regno] = 1;
  		  if (n_times_set[regno] < 127)
  		    ++n_times_set[regno];
+ 		  /* intel1 */
+ 		  if (doing_loop_after_global 
+ 		     && HARD_REGNO_NREGS (regno, GET_MODE (dest)) > 1)
+ 		    { /* Count each hard reg in the group.  */
+ 		        register int i,next_regno;
+ 
+ 		        i = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+ 		        next_regno = regno + 1;
+ 		        while (i!=1)
+ 		          {
+ 		              if (n_times_set[next_regno] < 127)
+ 		                ++n_times_set[next_regno];
+ 		              next_regno++;
+ 		              i--;
+ 		          }
+ 		    }
  		  last_set[regno] = insn;
  		}
  	    }
***************
*** 3244,3249 ****
--- 3608,3616 ----
    int call_seen;
    rtx test;
    rtx end_insert_before;
+   int try_compare_elimination, done_compare_elimination; /* intel1 */
+   rtx compare_insn, jump_insn, tinsn; /* intel1 */
+   int *times_reg_used; /* intel1 */
    int loop_depth = 0;
  
    reg_iv_type = (enum iv_mode *) alloca (max_reg_before_loop
***************
*** 3373,3379 ****
  	     will be executed if the loop is executed.  */
  	  && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  		&& ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
! 		    || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
  	not_every_iteration = 1;
  
        else if (GET_CODE (p) == NOTE)
--- 3740,3749 ----
  	     will be executed if the loop is executed.  */
  	  && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  		&& ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
!           || (NEXT_INSN (p) == loop_end && condjump_p (p))))
!      /*intel1*/  && !(GET_CODE (p) == JUMP_INSN
!                       && jumps_back_in_loop(p,loop_start,0,0))
!     )
  	not_every_iteration = 1;
  
        else if (GET_CODE (p) == NOTE)
***************
*** 3487,3492 ****
--- 3857,3874 ----
  	}
      }
  
+   /* Now see if it is wothwhile to do compare elimination, remember it only
+      saves one instruction.  intel1
+   */
+   try_compare_elimination = 0;
+   if (flag_compare_elim 
+      && loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]] == NULL)
+   {
+     possible_compare_elimination(loop_start, loop_end, &compare_insn, 
+                                  &jump_insn, &try_compare_elimination);
+     done_compare_elimination = 0;
+   }
+ 
    /* Look at the each biv and see if we can say anything better about its
       initial value from any initializing insns set up above.  (This is done
       in two passes to avoid missing SETs in a PARALLEL.)  */
***************
*** 3508,3513 ****
--- 3890,3910 ----
  	   || GET_MODE (src) == VOIDmode)
  	  && valid_initial_value_p (src, bl->init_insn, call_seen, loop_start))
  	{
+ 	  /* intel1 */
+ 	  if (flag_compare_elim && !flag_unroll_loops 
+ 	     && try_compare_elimination && !done_compare_elimination 
+ 	     && bl->biv_count == 1 
+ 	     && bl->biv->mult_val == const1_rtx 
+ 	     && REGNO (XEXP (SET_SRC (PATTERN (compare_insn)), 0)) == bl->regno 
+ 	     &&  (done_compare_elimination 
+ 	     = compare_elimination (bl, loop_start, loop_end, 
+ 	                         compare_insn, jump_insn,0)))
+ 	    {
+     	      rtx tem = find_reg_note (bl->init_insn, REG_EQUAL, 0);
+ 	      if (tem)
+ 		XEXP (tem, 0) = SET_SRC (bl->init_set);
+ 	      src = SET_SRC (bl->init_set);
+ 	    }
  	  bl->initial_value = src;
  
  	  if (loop_dump_stream)
***************
*** 3651,3657 ****
  	     will be executed if the loop is executed.  */
  	  && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  		&& ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
! 		    || (NEXT_INSN (p) == loop_end && condjump_p (p)))))
  	not_every_iteration = 1;
  
        else if (GET_CODE (p) == NOTE)
--- 4048,4057 ----
  	     will be executed if the loop is executed.  */
  	  && ! (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == loop_top
  		&& ((NEXT_INSN (NEXT_INSN (p)) == loop_end && simplejump_p (p))
!           || (NEXT_INSN (p) == loop_end && condjump_p (p))))
!      /*intel1*/ && !(GET_CODE (p) == JUMP_INSN
!                      && jumps_back_in_loop(p,loop_start,0,0))
!     )
  	not_every_iteration = 1;
  
        else if (GET_CODE (p) == NOTE)
***************
*** 3717,3722 ****
--- 4117,4128 ----
    for (bl = loop_iv_list; bl; bl = bl->next)
      {
        struct induction *v;
+       /* intel1 */
+ #ifdef SAVE_ON_REGS
+       int num_add_vals_live_outside =0;
+       int no_mem_givs = 0;
+       int contains_loop =0;
+ #endif
        int benefit;
        int all_reduced;
        rtx final_value = 0;
***************
*** 3774,3779 ****
--- 4180,4276 ----
  	 We can't (currently) eliminate the biv unless this is so.  */
        all_reduced = 1;
  
+       /* intel1 */
+ #ifdef SAVE_ON_REGS
+       /* Only reduce DEST_ADDR givs of this biv if they will not increase
+          register pressure.  
+       */
+       if (!flag_all_mem_givs && flag_opt_reg_use)
+         {
+           int num_mult_val_saved = 0;
+           int num_givs_to_update = 0;
+           num_add_vals_live_outside = 0;
+           no_mem_givs = 0;
+           contains_loop = loop_contains_loop (loop_start, end);
+         
+           for (v = bl->giv; v; v = v->next_iv)
+             {
+               if (v->giv_type == DEST_ADDR)
+                 num_mult_val_saved++;
+               if (v->giv_type == DEST_ADDR && !v->same)
+                 {
+                   num_givs_to_update++;
+                   if (v->add_val && GET_CODE (v->add_val) == REG 
+                      && REGNO (v->add_val) >= FIRST_PSEUDO_REGISTER 
+                      && (contains_loop 
+                          || REGNO (v->add_val)<max_reg_before_loop))
+                     {
+                       if (loop_dump_stream 
+                          && reg_live_outside_loop[REGNO (v->add_val)])
+                         {
+                           fprintf (loop_dump_stream, 
+                           "dest addr giv at %d has add_val live outside reg%d\n", 
+                           INSN_UID (v->insn), REGNO (v->add_val));
+                         }
+                       if (contains_loop)
+                         num_add_vals_live_outside += 2;
+                       else
+                         {
+                           num_add_vals_live_outside += 
+                             reg_live_outside_loop[REGNO (v->add_val)];
+                         }
+                     }
+                   else if (v->add_val && GET_CODE (v->add_val) == CONST_INT 
+                            && v->mult_val == const1_rtx)
+                     { /* Disable this reduction. */
+                       num_add_vals_live_outside = (1 << ((sizeof (int)*8)-4));
+                     }
+                 }
+             }
+ #ifdef MAX_DEST_ADDR_GIVS
+         if (num_givs_to_update > MAX_DEST_ADDR_GIVS)
+           {
+             no_mem_givs = 1;
+           }
+ #endif
+         /* Heuristic here:
+            a) If the biv is eliminated that saves one register in the loop.  
+            b) Each giv_to_update must be updated at the end of the loop.  
+            c) Each add_val_live_outside may cause a spill somewhere.  
+         */
+         if (loop_dump_stream)
+           {
+             fprintf (loop_dump_stream,
+             "eliminable %d num_updates %d mults_saved %d adds_outside %d heu %d\n",
+             bl->eliminable, num_givs_to_update, num_mult_val_saved,
+             num_add_vals_live_outside,
+             (((int)(bl->eliminable) * -3) 
+              + (num_givs_to_update+((int)(bl->eliminable) * -1)) 
+              + (num_mult_val_saved*-1) +
+              + (num_add_vals_live_outside*3) 
+             ));
+           }
+         if (no_mem_givs 
+             ||  
+             (((int)(bl->eliminable) * -3) 
+              + (num_givs_to_update+((int)(bl->eliminable) * -1)) 
+              + (num_mult_val_saved*-1) +
+              + (num_add_vals_live_outside*3) > 0
+             )
+            )
+           {
+             all_reduced = 0;
+             for (v = bl->giv; v; v = v->next_iv)
+               {
+                 if (v->giv_type == DEST_ADDR)
+                   {
+                     v->ignore = 1;
+                   }
+               }
+           }
+       }
+ #endif /* SAVE_ON_REGS */
+ 
        /* Check each giv in this class to see if we will benefit by reducing
  	 it.  Skip giv's combined with others.  */
        for (v = bl->giv; v; v = v->next_iv)
***************
*** 3965,3971 ****
  		 loop to ensure that it will always be executed no matter
  		 how the loop exits.  Otherwise, emit the insn after the loop,
  		 since this is slightly more efficient.  */
! 	      if (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  		insert_before = loop_start;
  	      else
  		insert_before = end_insert_before;
--- 4462,4468 ----
  		 loop to ensure that it will always be executed no matter
  		 how the loop exits.  Otherwise, emit the insn after the loop,
  		 since this is slightly more efficient.  */
! 	      if (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  		insert_before = loop_start;
  	      else
  		insert_before = end_insert_before;
***************
*** 4032,4037 ****
--- 4529,4542 ----
  	 of the occurrences of the biv with a giv, but no harm was done in
  	 doing so in the rare cases where it can occur.  */
  
+       /* intel1 Retry compare elimination this time for loop trip test.  */
+       if (flag_compare_elim && !flag_unroll_loops 
+          && !done_compare_elimination && bl->retry_celim > 1 
+          && all_reduced == 1 && bl->eliminable)
+         {
+ 	  compare_elimination (bl, loop_start, loop_end, 
+                           compare_insn, jump_insn, 1);
+         } 
        if (all_reduced == 1 && bl->eliminable
  	  && maybe_eliminate_biv (bl, loop_start, end, 1,
  				  threshold, insn_count))
***************
*** 4057,4063 ****
  		 loop to ensure that it will always be executed no matter
  		 how the loop exits.  Otherwise, emit the insn after the
  		 loop, since this is slightly more efficient.  */
! 	      if (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  		insert_before = loop_start;
  	      else
  		insert_before = end_insert_before;
--- 4562,4568 ----
  		 loop to ensure that it will always be executed no matter
  		 how the loop exits.  Otherwise, emit the insn after the
  		 loop, since this is slightly more efficient.  */
! 	      if (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  		insert_before = loop_start;
  	      else
  		insert_before = end_insert_before;
***************
*** 4083,4088 ****
--- 4588,4606 ----
  	    fprintf (loop_dump_stream, "Reg %d: biv eliminated\n",
  		     bl->regno);
  	}
+       /* intel1 Retry compare elimination this time handling ashifhts. */
+       else if (flag_compare_elim && !flag_unroll_loops 
+                && !done_compare_elimination && bl->retry_celim == 1)
+         {
+ 	  if (compare_elimination (bl, loop_start, loop_end, 
+ 	                         compare_insn, jump_insn, 1))
+ 	    {
+     	      rtx tem = find_reg_note (bl->init_insn, REG_EQUAL, 0);
+ 	      if (tem)
+ 		XEXP (tem, 0) = SET_SRC (bl->init_set);
+  	      bl->initial_value = SET_SRC (bl->init_set);;
+ 	    }
+         } 
      }
  
    /* Go through all the instructions in the loop, making all the
***************
*** 4164,4169 ****
--- 4682,4689 ----
    register int i, j;
    register enum rtx_code code;
    register char *fmt;
+   /* intel1 */
+   rtx tx;
  
    if (x == 0)
      return;
***************
*** 4195,4200 ****
--- 4715,4738 ----
  	benefit = general_induction_var (XEXP (x, 0),
  					 &src_reg, &add_val, &mult_val);
  
+ 	/* intel1
+ 	   For now lets strip off consty and try to recoginze the result
+ 	   as a possible mem_giv.  */
+ #ifdef REWRITE_ADDRESS
+ 	if (flag_opt_reg_use
+ 	   && benefit == 0 && GET_CODE (XEXP (x, 0)) == PLUS 
+ 	   && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS 
+ 	   &&  (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 
+ 	    || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST 
+ 	    || GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF))
+ 	  {
+ 	    tx = x;
+ 	    x = XEXP (x, 0);
+ 	    benefit = general_induction_var (XEXP (x, 0),
+                                              &src_reg, &add_val, &mult_val);
+ 	  }
+ #endif
+ 
  	/* Don't make a DEST_ADDR giv with mult_val == 1 && add_val == 0.
  	   Such a giv isn't useful.  */
  	if (benefit > 0 && (mult_val != const1_rtx || add_val != const0_rtx))
***************
*** 4203,4208 ****
--- 4741,4765 ----
  	    struct induction *v
  	      = (struct induction *) oballoc (sizeof (struct induction));
  
+ /* intel1 */
+ #ifdef REDUCE_INDEX
+ #ifdef REWRITE_ADDRESS
+ #ifdef LEGITIMATE_INDEX_P
+ 	rtx * index_part;
+ 	/* try to eliminate index terms */		
+ 	if (REDUCE_INDEX && flag_reduce_index_givs
+ 	   && do_reduce_index (x, &add_val))
+ 	  { 
+ 	    index_part = &XEXP (XEXP (x, 0), 0);
+ 	    record_giv (v, insn, src_reg, addr_placeholder, mult_val,
+ 	               add_val, benefit, DEST_ADDR, not_every_iteration,
+ 	               index_part, loop_start, loop_end);
+ 	    v->is_index_induc = 1;
+ 	  }
+ 	else
+ #endif
+ #endif
+ #endif
  	    record_giv (v, insn, src_reg, addr_placeholder, mult_val,
  			add_val, benefit, DEST_ADDR, not_every_iteration,
  			&XEXP (x, 0), loop_start, loop_end);
***************
*** 4290,4295 ****
--- 4847,4854 ----
        bl->eliminable = 0;
        bl->nonneg = 0;
        bl->reversed = 0;
+       /* intel1 */
+       bl->retry_celim = 0;
        bl->total_benefit = 0;
  
        /* Add this class to loop_iv_list.  */
***************
*** 4374,4379 ****
--- 4933,4942 ----
    v->new_reg = 0;
    v->final_value = 0;
    v->same_insn = 0;
+   /* intel1 */
+ #ifdef REDUCE_INDEX
+   v->is_index_induc = 0;
+ #endif
  
    /* The v->always_computable field is used in update_giv_derive, to
       determine whether a giv can be used to derive another giv.  For a
***************
*** 4651,4657 ****
  
  	      if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
  		  && LABEL_NAME (JUMP_LABEL (p))
! 		  && ((INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
  		       && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
  		      || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
  			  && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
--- 5214,5221 ----
  
  	      if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p)
  		  && LABEL_NAME (JUMP_LABEL (p))
! 		  && ( INSN_UID(v->insn)>=max_uid_for_loop /* intel1 */
! 		      || (INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (v->insn)
  		       && INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop_start))
  		      || (INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (last_giv_use)
  			  && INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop_end))))
***************
*** 5474,5482 ****
       the expression of G2 in terms of G1 can be used.  */
    if (g2->giv_type == DEST_ADDR
        && (tem = express_from (g1, g2)) != 0
        && memory_address_p (g2->mem_mode, tem)
!       && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location))
      {
        g2->new_reg = tem;
        return 1;
      }
--- 6038,6063 ----
       the expression of G2 in terms of G1 can be used.  */
    if (g2->giv_type == DEST_ADDR
        && (tem = express_from (g1, g2)) != 0
+ /* intel1 */
+ #ifdef REDUCE_INDEX
+       && ((g2->is_index_induc && LEGITIMATE_INDEX_P(tem)) 
+            || (g2->is_index_induc == 0 && memory_address_p (g2->mem_mode, tem)
+            && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location))
+          )
+ #else
        && memory_address_p (g2->mem_mode, tem)
!       && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location)
! #endif
!      )
      {
+ /* intel1 */
+ #ifdef SAVE_ON_REGS
+       
+       if (flag_opt_reg_use && ADDRESS_COST (tem) != 1)
+       {
+         return(0);
+       }
+ #endif
        g2->new_reg = tem;
        return 1;
      }
***************
*** 5772,5778 ****
  	  num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
  
        if (bl->giv_count == 0
! 	  && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  	{
  	  rtx bivreg = regno_reg_rtx[bl->regno];
  
--- 6353,6359 ----
  	  num_nonfixed_reads += count_nonfixed_reads (PATTERN (p));
  
        if (bl->giv_count == 0
! 	  && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  	{
  	  rtx bivreg = regno_reg_rtx[bl->regno];
  
***************
*** 6274,6279 ****
--- 6855,6869 ----
        for (v = bl->giv; v; v = v->next_iv)
  	if (v->giv_type == DEST_ADDR && v->location == &XEXP (x, 0))
  	  return 1;
+ /* intel1 */
+ #ifdef REDUCE_INDEX
+ #ifdef LEGITIMATE_INDEX_P
+       for (v = bl->giv; v; v = v->next_iv)
+ 	if (REDUCE_INDEX && v->giv_type == DEST_ADDR && v->is_index_induc 
+ 	    && v->location == &XEXP (XEXP(x,0), 0))
+ 	  return 1;
+ #endif
+ #endif
        break;
      }
  
***************
*** 6628,6631 ****
--- 7218,13765 ----
  
    return gen_rtx (swap_condition (GET_CODE (comparison)), VOIDmode,
  		  XEXP (comparison, 1), XEXP (comparison, 0));
+ }
+ 
+ /* new code added by intel1 */
+ struct new_rtx
+   {
+     rtx pat;
+     rtx insn;
+     rtx supplemental_pat;	/* Pattern that should be
+ 				   emited after this insn.  */
+     struct new_rtx *next;
+   };
+ 
+ /* If bl is also the loop counter try to optimize out the
+    compare instruction by counting up to 0.  Return 1 if
+    successful.
+ */
+ static
+ int 
+ compare_elimination (bl, loop_start, loop_end, compare_insn, jump_insn, second_time)
+      struct iv_class *bl;
+      rtx loop_start, loop_end, compare_insn, jump_insn;
+      int second_time;
+ {
+   rtx insn, new_init_src, copy_of_jump, new_biv_set, loop_trip_reg;
+   int init_val, compare_val, i, adjust_val, desired_init_val;
+   int num_times_loop_execs, add_one, biv_init_to_const, biv_end_value;
+   int num_sups, compare_to_const;
+   struct new_rtx *new_rtx_element, *new_rtx_head, *new_rtx_tail;
+   char *storage;
+ 
+ 
+   if (GET_CODE (SET_DEST (bl->init_set)) != REG)
+     {
+       return (0);
+     }
+   if (!rtx_equal_p (SET_DEST (bl->init_set),
+ 		    XEXP (SET_SRC (PATTERN (compare_insn)), 0))
+     )
+     {
+       return (0);
+     }
+   copy_of_jump = copy_rtx (PATTERN (jump_insn));
+   PUT_CODE (XEXP (SET_SRC (copy_of_jump), 0), NE);
+   if (recog (copy_of_jump, jump_insn, 0) == -1)
+     {
+       return (0);
+     }
+   if (GET_CODE (XEXP (SET_SRC (PATTERN (compare_insn)), 1)) == CONST_INT)
+     {
+       if (bl->initial_test != NULL)
+ 	{
+ 	  return (0);
+ 	}
+       compare_val = INTVAL (XEXP (SET_SRC (PATTERN (compare_insn)), 1));
+       compare_to_const = 1;
+     }
+   else
+     {
+       compare_to_const = 0;
+       if (INTVAL (bl->biv->add_val) != 1)
+ 	{
+ 	  return (0);
+ 	}
+       else if (second_time == 0)
+ 	{
+ 	  bl->retry_celim = 2;	/* Signals that this is loop trip test
+ 	                           candidate.  */
+ 	  return (0);
+ 	}
+     }
+   if (GET_CODE (SET_SRC (bl->init_set)) != CONST_INT)
+     {
+       if (!compare_to_const)
+ 	{
+ 	  return (0);
+ 	}
+       else
+ 	{
+ 	  if (abs (INTVAL (bl->biv->add_val)) != 1)
+ 	    {
+ 	      return (0);
+ 	    }
+ 	  biv_init_to_const = 0;
+ 	  /* Just so checks on LE GE ... pass.  */
+ 	  init_val = compare_val - INTVAL (bl->biv->add_val);
+ 	}
+     }
+   else
+     {
+       init_val = INTVAL (SET_SRC (bl->init_set));
+       biv_init_to_const = 1;
+     }
+   insn = PREV_INSN (compare_insn);
+   while (GET_CODE (insn) == NOTE)
+     {
+       insn = PREV_INSN (insn);
+     }
+   if (!(GET_CODE (insn) == INSN 
+ 	&& rtx_equal_p (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set)) 
+ 	&& bl->biv->insn == insn))
+     {
+       return (0);
+     }
+   switch (GET_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0)))
+     {
+     case LE:
+       if (compare_to_const 
+ 	  && (INTVAL (bl->biv->add_val) <= 0 || compare_val < init_val))
+ 	{
+ 	  return (0);
+ 	}
+       add_one = 1;
+       break;
+ 
+     case GE:
+       if (compare_to_const 
+ 	  && (INTVAL (bl->biv->add_val) >= 0 || compare_val > init_val))
+ 	{
+ 	  return (0);
+ 	}
+       add_one = 1;
+       break;
+ 
+     case LT:
+       if (compare_to_const 
+ 	  && (INTVAL (bl->biv->add_val) <= 0 || compare_val <= init_val))
+ 	{
+ 	  return (0);
+ 	}
+       add_one = 0;
+       break;
+ 
+     case GT:
+       if (compare_to_const 
+ 	  && (INTVAL (bl->biv->add_val) >= 0 || compare_val >= init_val))
+ 	{
+ 	  return (0);
+ 	}
+       add_one = 0;
+       break;
+ 
+     default:
+       return (0);
+     }
+   if (!compare_to_const)
+     { /* We are doing loop trip test.  */
+       if (n_times_set[REGNO (XEXP (SET_SRC (PATTERN (compare_insn)), 1))])
+ 	{
+ 	  return (0);
+ 	}
+       loop_trip_reg = gen_reg_rtx (GET_MODE (SET_DEST (bl->init_set)));
+       desired_init_val = (-1 * init_val) + add_one;
+       /* Emit insn to initialize loop trip reg.  */
+       if (desired_init_val)
+ 	{
+ 	  emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
+ 				     gen_rtx (PLUS, GET_MODE (loop_trip_reg),
+ 				 XEXP (SET_SRC (PATTERN (compare_insn)), 1),
+ 				 gen_rtx (CONST_INT, 0, desired_init_val))),
+ 			    loop_start);
+ 	}
+       else
+ 	{
+ 	  emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
+ 				XEXP (SET_SRC (PATTERN (compare_insn)), 1)),
+ 			    loop_start);
+ 	}
+       /* Emit insn to decrement loop trip reg.  */
+       emit_insn_before (gen_rtx (SET, 0, loop_trip_reg,
+ 				 gen_rtx (PLUS, GET_MODE (loop_trip_reg),
+ 					  loop_trip_reg,
+ 					  gen_rtx (CONST_INT, 0, -1))),
+ 			compare_insn);
+       /* Change comparison */
+       XEXP (SET_SRC (PATTERN (compare_insn)), 1) = const0_rtx;
+       XEXP (SET_SRC (PATTERN (compare_insn)), 0) = loop_trip_reg;
+       /* Change jump insn */
+       PUT_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0), NE);
+       INSN_CODE (jump_insn) = recog (PATTERN (jump_insn), jump_insn, 0);
+       bl->retry_celim = 0;
+       return (1);
+     }
+   if (biv_init_to_const)
+     {
+       num_times_loop_execs
+ 	  = ((abs (compare_val - init_val) + add_one - 1) / abs (INTVAL (bl->biv->add_val))) + 1;
+       desired_init_val = -1 * num_times_loop_execs * INTVAL (bl->biv->add_val);
+       adjust_val = init_val - desired_init_val;
+       new_init_src = gen_rtx (CONST_INT, 0, desired_init_val);
+ 
+       biv_end_value = num_times_loop_execs * INTVAL (bl->biv->add_val) + init_val;
+ 
+     }
+   else
+     {/* biv is incremented by +-1 so the adjust_val is */
+       adjust_val 
+ 	  = (compare_val + (add_one * INTVAL (bl->biv->add_val)));
+       desired_init_val = -1 * adjust_val;
+       biv_end_value = compare_val + (add_one * INTVAL (bl->biv->add_val));
+       /* Make a check that we will be able to adjust the bivs init_val
+          by desired_init_val.  */
+       new_init_src = gen_rtx (PLUS, GET_MODE (SET_DEST (bl->init_set)),
+ 			      SET_SRC (bl->init_set),
+ 			      gen_rtx (CONST_INT, 0, desired_init_val));
+       new_biv_set = gen_rtx (SET, GET_MODE (SET_SRC (bl->init_set)),
+ 			     SET_DEST (bl->init_set), new_init_src);
+       if (recog (new_biv_set, bl->init_set, 0) == -1)
+ 	{
+ 	  return (0);
+ 	}
+     }
+   /* Now see if we can replace register bl->regno with
+      bl->regno+(adjust_val) in all insns from bl->init_insn to
+      loop_end.  
+      Signal that if we fail we should retry again at the end of
+      strength reduction.  */
+   if (second_time == 0)
+     {
+       bl->retry_celim = 1;
+     }
+   /* Mark our place on the obstack in case of failure.  */
+   storage = (char *) oballoc (0);
+   num_sups = 0;
+   new_rtx_head = new_rtx_tail = NULL;
+   insn = NEXT_INSN (bl->init_insn);
+   while (insn != compare_insn)
+     {
+       if (GET_CODE (insn) == INSN 
+ 	  && !rtx_equal_p (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set)))
+ 	{
+ 	  new_rtx_element = (struct new_rtx *) alloca (sizeof (struct new_rtx));
+ 	  new_rtx_element->insn = insn;
+ 	  new_rtx_element->supplemental_pat = NULL;
+ 	  if (!attempt_new_rtx (new_rtx_element, insn, bl, adjust_val, second_time))
+ 	    {
+ 	      obfree (storage);
+ 	      return (0);
+ 	    }
+ 	  else if (!rtx_equal_p (SET_SRC (insn), SET_SRC (new_rtx_element->pat)) 
+ 	    || !rtx_equal_p (SET_DEST (insn), SET_DEST (new_rtx_element->pat)))
+ 	    {
+ 	      if (new_rtx_head == NULL)
+ 		{
+ 		  new_rtx_head = new_rtx_element;
+ 		}
+ 	      else
+ 		{
+ 		  new_rtx_tail->next = new_rtx_element;
+ 		}
+ 	      new_rtx_tail = new_rtx_element;
+ 	      new_rtx_element->next = 0;
+ 	    }
+ 	  if (new_rtx_element->supplemental_pat)
+ 	    {
+ 	      num_sups++;
+ 	      if (num_sups > 3)
+ 		{ /* heuristic */
+ 		  obfree (storage);
+ 		  return (0);
+ 		}
+ 	    }
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   /* Replacement can be done now do it.  */
+   new_rtx_element = new_rtx_head;
+   while (new_rtx_element)
+     {
+       PATTERN (new_rtx_element->insn) = new_rtx_element->pat;
+       if (new_rtx_element->supplemental_pat)
+ 	{
+ 	  emit_insn_after (
+ 		gen_move_insn (SET_DEST (new_rtx_element->supplemental_pat),
+ 			       SET_SRC (new_rtx_element->supplemental_pat)),
+ 			    new_rtx_element->insn);
+ 	}
+       new_rtx_element = new_rtx_element->next;
+     }
+   /* Finally update the initialization and comparison of the biv.  */
+   PUT_CODE (XEXP (SET_SRC (PATTERN (jump_insn)), 0), NE);
+   INSN_CODE (jump_insn) = recog (PATTERN (jump_insn), jump_insn, 0);
+   XEXP (SET_SRC (PATTERN (compare_insn)), 1) = const0_rtx;
+   SET_SRC (bl->init_set) = new_init_src;
+   INSN_CODE (bl->init_insn) = recog ( PATTERN (bl->init_insn), bl->init_insn, 0);
+   emit_insn_after (gen_rtx (SET, GET_MODE (SET_DEST (bl->init_set)),
+ 			    SET_DEST (bl->init_set),
+ 			    gen_rtx (CONST_INT, 0, biv_end_value)),
+ 		   loop_end);
+   bl->retry_celim = 0;
+   return (1);
+ 
+ }
+ 
+ /* Try to rewrite insn replacing the biv with biv+biv_adjust_const.  if
+    the substitution is not immediately recognizable then try to
+    rewrite the insn to make it recognizable.  If try_supplemental is 1
+    then an additional insn may be generated to make the substitution
+    recognizable.  The generated pattern is pointed to by
+    new_rtx_element->pat.  
+ */
+ static 
+ attempt_new_rtx (new_rtx_element, insn, bl, biv_adjust_const, try_supplemental)
+      rtx insn;
+      struct new_rtx *new_rtx_element;
+      struct iv_class *bl;
+      int biv_adjust_const;
+      int try_supplemental;
+ {
+   rtx new_src, new_dest, make_new_use (), try_to_make_good ();
+ 
+   new_src 
+      = make_new_use (SET_SRC (PATTERN (insn)), SET_DEST (bl->init_set),
+ 		  biv_adjust_const, insn);
+   new_dest 
+     = make_new_use (SET_DEST (PATTERN (insn)), SET_DEST (bl->init_set),
+ 		  biv_adjust_const, insn);
+   new_rtx_element->pat = gen_rtx (SET, 0, new_dest, new_src);
+   if (recog (new_rtx_element->pat, insn, 0) < 0)
+     {
+       try_to_make_good (SET_SRC (new_rtx_element->pat));
+       try_to_make_good (SET_DEST (new_rtx_element->pat));
+     }
+   if (recog (new_rtx_element->pat, insn, 0) < 0)
+     {
+       if (!try_supplemental)
+ 	{
+ 	  return (0);
+ 	}
+       if (GET_CODE (SET_DEST (new_rtx_element->pat)) == REG 
+ 	  && GET_CODE (SET_SRC (new_rtx_element->pat)) == ASHIFT 
+ 	  && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 0)) == PLUS 
+ 	  && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 1)) == CONST_INT 
+           && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 0)) == REG 
+ 	  && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 1)) == CONST_INT
+ 	)
+ 	{
+ 	  /* try to rewrite:
+            (set (reg:SI x)
+               (ashift:SI (plus:SI (reg/v:SI y)
+                                   (const_int a))
+                          (const_int b)))
+ 
+            into two patterns:
+            (set (reg:SI x)
+               (ashift:SI (reg/v:SI y)
+                          (const_int b)))
+ 
+            (set (reg:SI x)
+               (plus:SI (reg/v:SI x)
+                        (const_int a*(2**b))))
+         */
+ 	  int add_val;
+ 	  add_val 
+ 	    = two_to_power (INTVAL (XEXP (SET_SRC (new_rtx_element->pat), 1))) 
+ 	      * INTVAL (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 0), 1));
+ 	  new_rtx_element->pat = PATTERN (new_rtx_element->insn);
+ 	  new_rtx_element->supplemental_pat 
+ 	    = gen_rtx (SET, GET_MODE (SET_DEST (new_rtx_element->pat)),
+ 		     SET_DEST (new_rtx_element->pat),
+ 	  gen_rtx (PLUS, GET_MODE (XEXP (SET_SRC (new_rtx_element->pat), 0)),
+ 		   SET_DEST (new_rtx_element->pat),
+ 		   gen_rtx (CONST_INT, 0, add_val)));
+ 	}
+       else if (GET_CODE (SET_DEST (new_rtx_element->pat)) == REG 
+ 	       && GET_CODE (SET_SRC (new_rtx_element->pat)) == PLUS 
+ 	       && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 0)) == REG 
+ 	       && GET_CODE (XEXP (SET_SRC (new_rtx_element->pat), 1)) == PLUS 
+ 	       && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 0)) == REG 
+ 	       && GET_CODE (XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 1)) == CONST_INT
+ 	)
+ 	{
+ 	  /* try to rewrite:
+            (set (reg:SI x)
+                 (plus:SI (reg:SI y)
+                           (plus:SI   (reg:SI z)
+                                      (const_int a))))
+ 
+            into two patterns:
+            (set (reg:SI x)
+               (plus:SI (reg/v:SI y)
+                        (reg/v:SI z)))
+ 
+            (set (reg:SI x)
+               (plus:SI (reg/v:SI x)
+                        (const_int a)))
+         */
+ 	  new_rtx_element->supplemental_pat 
+ 	    = gen_rtx (SET, GET_MODE (SET_DEST (new_rtx_element->pat)),
+ 		     SET_DEST (new_rtx_element->pat),
+ 	  gen_rtx (PLUS, GET_MODE (XEXP (SET_SRC (new_rtx_element->pat), 0)),
+ 		   SET_DEST (new_rtx_element->pat),
+ 		   XEXP (XEXP (SET_SRC (new_rtx_element->pat), 1), 1)));
+ 	  new_rtx_element->pat = PATTERN (new_rtx_element->insn);
+ 	}
+       else
+ 	{
+ 	  return (0);
+ 	}
+       if (recog (new_rtx_element->supplemental_pat, insn, 0) < 0)
+ 	{
+ 	  return (0);
+ 	}
+     }
+   return (1);
+ }
+ 
+ 
+ /* Generate a new rtx which is a copy of orig with each occurence of
+    biv_reg replaced by biv_reg+biv_adjust_const.  
+ */
+ static rtx
+ make_new_use (orig, biv_reg, biv_adjust_const, insn)
+      register rtx orig, biv_reg;
+      rtx insn;
+      int biv_adjust_const;
+ {
+   register rtx copy;
+   rtx non_biv_operand, ret_rtx;
+   register int i, j;
+   register RTX_CODE code;
+   register char *format_ptr;
+ 
+   code = GET_CODE (orig);
+ 
+   switch (code)
+     {
+     case REG:
+       if (rtx_equal_p (orig, biv_reg))
+ 	{
+ 	  ret_rtx 
+ 	    = gen_rtx (PLUS, GET_MODE (orig), orig,
+ 		     gen_rtx (CONST_INT, 0, biv_adjust_const));
+ 	  return (ret_rtx);
+ 	}
+       else
+ 	{
+ 	  return (orig);
+ 	}
+       break;
+ 
+     case PLUS:
+     case MINUS:
+       if (GET_CODE (XEXP (orig, 0)) == REG && GET_CODE (XEXP (orig, 1)) == CONST_INT 
+ 	  && rtx_equal_p (XEXP (orig, 0), biv_reg))
+ 	{ /* Ajdust the const_int part by biv_adjust_const.  */
+ 	  if (GET_CODE (orig) == PLUS)
+ 	    {
+ 	      non_biv_operand 
+ 		   = gen_rtx (CONST_INT, 0,
+ 			 INTVAL (XEXP (orig, 1)) + biv_adjust_const);
+ 	    }
+ 	  else
+ 	    {
+ 	      non_biv_operand 
+ 		= gen_rtx (CONST_INT, 0,
+ 			 INTVAL (XEXP (orig, 1)) - biv_adjust_const);
+ 	    }
+ 	  ret_rtx = gen_rtx (code, GET_MODE (orig), XEXP (orig, 0), non_biv_operand);
+ 	  return (ret_rtx);
+ 	}
+       else
+ 	/* commutativity */ 
+ 	if (GET_CODE (XEXP (orig, 1)) == REG && GET_CODE (XEXP (orig, 0)) == CONST_INT 
+ 	    && rtx_equal_p (XEXP (orig, 1), biv_reg))
+ 	{/* Ajdust the const_int part by biv_adjust_const.  */
+ 	  if (GET_CODE (orig) == PLUS)
+ 	    {
+ 	      non_biv_operand 
+ 		= gen_rtx (CONST_INT, 0,
+ 			 INTVAL (XEXP (orig, 0)) + biv_adjust_const);
+ 	    }
+ 	  else
+ 	    {
+ 	      non_biv_operand 
+ 		= gen_rtx (CONST_INT, 0,
+ 			 INTVAL (XEXP (orig, 0)) - biv_adjust_const);
+ 	    }
+ 	  ret_rtx = gen_rtx (code, GET_MODE (orig), non_biv_operand, XEXP (orig, 1));
+ 	  return (ret_rtx);
+ 	}
+       break;
+ 
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+     case PC:
+     case CC0:
+       return orig;
+     }
+ 
+   copy = rtx_alloc (code);
+   PUT_MODE (copy, GET_MODE (orig));
+   copy->in_struct = orig->in_struct;
+   copy->volatil = orig->volatil;
+   copy->unchanging = orig->unchanging;
+   copy->integrated = orig->integrated;
+ 
+   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
+ 
+   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
+     {
+       switch (*format_ptr++)
+ 	{
+ 	case 'e':
+ 	  XEXP (copy, i) = XEXP (orig, i);
+ 	  if (XEXP (orig, i) != NULL)
+ 	    XEXP (copy, i) 
+ 	      = make_new_use (XEXP (orig, i), biv_reg,
+ 			    biv_adjust_const, insn);
+ 	  break;
+ 
+ 	case 'E':
+ 	case 'V':
+ 	  XVEC (copy, i) = XVEC (orig, i);
+ 	  if (XVEC (orig, i) != NULL)
+ 	    {
+ 	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
+ 	      for (j = 0; j < XVECLEN (copy, i); j++)
+ 		XVECEXP (copy, i, j) 
+ 		  = make_new_use (XVECEXP (orig, i, j), biv_reg,
+ 				biv_adjust_const, insn);
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  XINT (copy, i) = XINT (orig, i);
+ 	  break;
+ 	}
+     }
+   return copy;
+ }
+ 
+ /* Try to put orig into a form that is recognizable using rewrite_address
+    on the relevant portion of orig.  
+ */
+ rtx
+ try_to_make_good (orig)
+      register rtx orig;
+ {
+   void rewrite_address ();
+   register int i, j;
+   register RTX_CODE code;
+   register char *fmt;
+ 
+   code = GET_CODE (orig);
+ 
+   switch (code)
+     {
+     case REG:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+     case PC:
+     case CC0:
+       return orig;
+ 
+     case MEM:
+       GO_IF_LEGITIMATE_ADDRESS (GET_MODE (orig), orig, memok);
+ #ifdef REWRITE_ADDRESS
+       REWRITE_ADDRESS (orig);
+ #endif
+     memok:
+       return (orig);
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       XEXP (orig, i) = try_to_make_good (XEXP (orig, i));
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (orig, i); j++)
+ 	  XVECEXP (orig, i, j) 
+ 	    = try_to_make_good (XVECEXP (orig, i, j));
+       }
+   return orig;
+ }
+ 
+ 
+ /* Check to see if compare elimination is possible for this loop.  
+    Return 1 if yes and set up *compare_insn to point to the compare
+    at the end of the loop and *jump_insn to point to the jump back
+    to the beginning of the loop.  
+ */
+ static int
+ possible_compare_elimination (loop_start, loop_end, compare_insn, jump_insn, try_compare_elimination)
+      rtx loop_end, loop_start, *compare_insn, *jump_insn;
+      int *try_compare_elimination;
+ {
+   rtx insn;
+   int i;
+   insn = loop_start;
+   i = 0;
+   *try_compare_elimination = 0;
+   while (insn && insn != loop_end)
+     {
+       if (GET_CODE (insn) == CALL_INSN)
+ 	{
+ 	  insn = NULL;
+ 	}
+       else if (GET_CODE (insn) == INSN)
+ 	{
+ 	  i++;
+ 	  if (i > MAX_CMP_ELIM)
+ 	    {
+ 	      insn = NULL;
+ 	    }
+ 	  else if (GET_CODE (PATTERN (insn)) != SET)
+ 	    {
+ 	      insn = NULL;
+ 	    }
+ 	}
+       if (insn)
+ 	insn = NEXT_INSN (insn);
+     }
+   if (insn != NULL)
+     {
+       *try_compare_elimination = 1;
+     }
+   /* Look for compare jcc on this biv at the end of the loop.  */
+   insn = PREV_INSN (loop_end);
+   if (!(GET_CODE (insn) == JUMP_INSN 
+ 	&& GET_CODE (PATTERN (insn)) == SET 
+ 	&& SET_DEST (PATTERN (insn)) == pc_rtx 
+ 	&& GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE 
+ 	&& XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0) == cc0_rtx 
+ 	&& XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1) == const0_rtx))
+     {
+       *try_compare_elimination = 0;
+     }
+   *jump_insn = insn;
+   insn = PREV_INSN (insn);
+   if (!(GET_CODE (insn) == INSN 
+ 	&& GET_CODE (PATTERN (insn)) == SET 
+ 	&& SET_DEST (PATTERN (insn)) == cc0_rtx 
+ 	&& GET_CODE (SET_SRC (PATTERN (insn))) == COMPARE 
+ 	&& (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT 
+ 	    || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == REG) 
+ 	&& GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG))
+     {
+       *try_compare_elimination = 0;
+     }
+   *compare_insn = insn;
+ }
+ 
+ struct regs_mentioned
+   {
+     rtx reg;				/* The register.  */
+     int in_mem;				/* Is 1 if register is part of
+     					   a MEM_REF.  */
+     struct regs_mentioned *next;
+   };
+    
+ static struct regs_mentioned *giv_reg_header = NULL, *use_reg_header = NULL;
+ 
+ /* Build a linked list of (struct regs_mentioned) describing the
+    registers used in the pattern pat.  The head of the linked list
+    to place them on is a_header.  If in_mem is 1 this means that
+    pat is subexpression of a MEM_REF.  
+ */
+ static void
+ find_regs_mentioned (pat, a_header, in_mem)
+      rtx pat;
+      struct regs_mentioned **a_header;
+      int in_mem;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+   struct regs_mentioned *one_reg;
+ 
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+     case REG:
+       if (REGNO (pat) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  return;
+ 	}
+       one_reg = (struct regs_mentioned *)
+ 	obstack_alloc (&momentary_obstack, sizeof (struct regs_mentioned));
+       one_reg->reg = pat;
+       one_reg->in_mem = in_mem;
+       one_reg->next = *a_header;
+       *a_header = one_reg;
+       return;
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return;
+ 
+     case MEM:
+       in_mem = 1;
+       break;
+ 
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    find_regs_mentioned (XVECEXP (pat, i, j), a_header, in_mem);
+ 	}
+       else if (fmt[i] == 'e')
+ 	find_regs_mentioned (XEXP (pat, i), a_header, in_mem);
+     }
+ }
+ 
+ #ifdef REDUCE_INDEX
+ /* Create givs which are only index terms of memory addresses.  */
+ static int
+ do_reduce_index (x, add_val)
+      rtx x, *add_val;
+ {
+   rtx mem_address, sym_part, constint_part, save_add_val;
+   save_add_val = *add_val;
+   mem_address = XEXP (x, 0);
+   if (GET_CODE (mem_address) != PLUS)
+     {
+       return (0);
+     }
+   if (GET_CODE (XEXP (mem_address, 0)) == MULT)
+     {
+       if (!LEGITIMATE_INDEX_P (XEXP (mem_address, 0)) 
+ 	  || GET_CODE (XEXP (mem_address, 1)) == REG	
+ 	)
+ 	{ /* Will have index term anyway.  */
+ 	  return (0);
+ 	}
+     }
+   else
+     {
+       return (0);
+     }
+   /* Strip from *(add_val) the non index part.  */
+   if (rtx_equal_p (*(add_val), XEXP (mem_address, 1)))
+     {
+       *(add_val) = const0_rtx;
+     }
+   else if (GET_CODE (*(add_val)) == CONST_INT)
+     {
+       if (GET_CODE (XEXP (mem_address, 1)) != CONST_INT)
+ 	{
+ 	  return (0);
+ 	}
+       else
+ 	{
+ 	  *(add_val) 
+ 	    = gen_rtx (CONST_INT, 0,
+ 		      INTVAL (*(add_val)) - INTVAL (XEXP (mem_address, 1)));
+ 	}
+     }
+   else if (GET_CODE (*(add_val)) == CONST)
+     {
+       if (!(GET_CODE (XEXP (*(add_val), 0)) == PLUS 
+ 	    && GET_CODE (XEXP (XEXP (*(add_val), 0), 0)) == SYMBOL_REF 
+ 	    && GET_CODE (XEXP (XEXP (*(add_val), 0), 1)) == CONST_INT)
+ 	)
+ 	{
+ 	  return (0);
+ 	}
+       *(add_val) = XEXP (*(add_val), 0);
+       mem_address = XEXP (mem_address, 1);
+       if (GET_CODE (mem_address) == CONST)
+ 	{
+ 	  mem_address = XEXP (mem_address, 0);
+ 	}
+       if (GET_CODE (mem_address) == PLUS)
+ 	{
+ 	  sym_part = XEXP (mem_address, 0);
+ 	  constint_part = XEXP (mem_address, 1);
+ 	}
+       else
+ 	{
+ 	  sym_part = mem_address;
+ 	  constint_part = const0_rtx;
+ 	}
+       if (!rtx_equal_p (XEXP (*(add_val), 0), sym_part))
+ 	{
+ 	  *(add_val) = save_add_val;
+ 	  return (0);
+ 	}
+       else
+ 	{
+ 	  *(add_val) = XEXP (*(add_val), 1);
+ 	  *(add_val) 
+ 	    = gen_rtx (CONST_INT, 0, INTVAL (*(add_val)) - INTVAL (constint_part));
+ 	}
+     }
+   else
+     {
+       return (0);
+     }
+   return (1);
+ }
+ 
+ #endif
+ 
+ struct regopt_info
+ {
+   rtx insn_set;		/* The insn that loads the current value in the register */
+   rtx corresp_mem;	/* The memory that contains the same value as the register */
+   rtx reg; 		/* The register */
+   char replace_reg;	/* If 1 replace reg with corresp_mem (for stack regs)
+ 			   otherwise replace corresp_mem with reg */
+   char do_replace;	/* If 1 then this is a stack reg that has already
+ 			   been used in this extended basic block -
+ 			   try to replace susequent uses with this regs
+ 			   corresponding mem */
+ };
+ static struct regopt_info *rinfo;
+ struct undo
+ {
+   rtx *where;
+   rtx old_contents;
+   int is_int;
+ };
+ 
+ #define MAX_UNDO 50
+ 
+ struct undobuf
+ {
+   int num_undo;
+   char *storage;
+   struct undo undo[MAX_UNDO];
+   rtx other_insn;
+ };
+ 
+ static struct undobuf undobuf;
+ #define LOOP_SUBST(WHERE, NEWVAL)  \
+  do { if (undobuf.num_undo < MAX_UNDO)					\
+ 	{								\
+ 	  undobuf.undo[undobuf.num_undo].where = WHERE;			\
+ 	  undobuf.undo[undobuf.num_undo].old_contents = *WHERE;		\
+ 	  undobuf.undo[undobuf.num_undo].is_int = 0;			\
+ 	  *WHERE = NEWVAL;						\
+ 	  undobuf.num_undo++;						\
+ 	}								\
+     } while (0)
+ 
+ 
+ static int mem_max_reg_num;
+ #define SYMREF_PLUS_REG(insn)						\
+      (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS &&			\
+      GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG && 		\
+      GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF)
+ 
+ /*  Try to replace a register use with the value that sets that the
+     register.  This is done for the following cases:
+     1) regx <- regy ashift const_int
+     2) regx <- symbol_ref + regy
+     3) regx <- (regy * const_int) + const_int
+ 
+     If only_symref_plus_reg==1 then regx is replaced only if it
+     used as a base or index register and is of type 2)
+     otherwise it is always replaced.  
+ 
+     Calling use_regs_source with only_symref_plus_reg==0 on a loop
+     before strength reduction causes strength reduction to better handle
+     mem givs.  
+ 
+     Calling use_regs_source with only_symref_plus_reg==1 at the end of
+     loop optimization will do the replacement even if combine would not.  
+ 
+     also if only_symref_plus_reg==1 and if we have
+     1) mem1 <- regx
+     then attempt to replace susequent uses of mem1 with regx
+ 
+ 
+ */
+ 
+ static
+ void 
+ use_regs_source (start, end, only_symref_plus_reg)
+      rtx start, end;
+      int only_symref_plus_reg;
+ {
+   rtx insn, src, new_src, dest, tinsn, tmp_rtx;
+   struct regs_mentioned *header, *a_reg_used;
+   int recog_ok, i, insn_code_num, nested;
+   char *storage1, *storage2;
+   int cur_max_reg = max_reg_num () + 1;
+   mem_max_reg_num = cur_max_reg;
+ 
+   undobuf.num_undo = 0;
+   rinfo 
+     = (struct regopt_info *) alloca (cur_max_reg * sizeof (struct regopt_info));
+   bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 
+   nested = 0;
+   insn = NEXT_INSN (start);
+   while (insn != end)
+     {
+       switch (GET_CODE (insn))
+ 	{
+ 
+ 	case NOTE:
+ 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 
+ 	      && only_symref_plus_reg)
+ 	    {
+ 	      nested++;
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END 
+ 	      && only_symref_plus_reg)
+ 	    {
+ 	      nested--;
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  break;
+ 
+ 	case JUMP_INSN:
+ 	  if (nested == 0 || !only_symref_plus_reg)
+ 	    {
+ 	      if (SET_DEST (PATTERN (insn)) == pc_rtx
+ 		  && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF)
+ 		{
+ 		  bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 		}
+ 	      else if (!only_symref_plus_reg)
+ 		{
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      rinfo[i].corresp_mem = NULL;
+ 		    }
+ 		}
+ 	    }
+ 	  break;
+ 
+ 	case CALL_INSN:
+ 	  if (nested == 0 || !only_symref_plus_reg)
+ 	    {
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  break;
+ 
+ 	case CODE_LABEL:
+ 	case BARRIER:
+ 	  if (nested == 0 || !only_symref_plus_reg)
+ 	    {
+ 	      /* Forget everything */
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  break;
+ 
+ 	case INSN:
+ 	  if (!(nested == 0 || !only_symref_plus_reg))
+ 	    break;
+           if (GET_CODE (PATTERN (insn)) == CLOBBER)
+             {
+               dest = SET_DEST (PATTERN (insn));
+ 	      if (GET_CODE (dest) == REG)
+ 		{
+ 		  rinfo[ REGNO (dest)].insn_set = NULL;
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].insn_set
+ 			  && reg_overlap_mentioned_p (dest, 
+ 			        SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			)
+ 			{ /* current value of reg dest overwritten */
+ 			  rinfo[i].insn_set = NULL;
+ 		          if (rinfo[i].corresp_mem 
+ 		              && reg_overlap_mentioned_p (dest, 
+ 		                   rinfo[i].corresp_mem))
+ 			    { /* Not the same memory address anymore.  */
+ 			      rinfo[i].corresp_mem = NULL;
+ 			    }
+ 			}
+ 		    }
+ 		}
+ 	      else if (GET_CODE (dest) == MEM && !only_symref_plus_reg 
+ 		       && flag_replace_mem)
+ 		{
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].corresp_mem 
+ 			  && true_dependence (dest, rinfo[i].corresp_mem))
+ 			{ /* Memory address maybe overwritten.  */
+ 			  rinfo[i].corresp_mem = NULL;
+ 			}
+ 		    }
+ 		}
+ 			} else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	    {
+ 				dest = SET_DEST (PATTERN (insn));
+ 	      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ 		{
+ 		  rtx cur_rtx;
+ 		  cur_rtx = XVECEXP (PATTERN (insn), 0, i);
+ 		  if ((GET_CODE (cur_rtx) == SET || GET_CODE (cur_rtx) == CLOBBER)
+ 		      && GET_CODE (SET_DEST (cur_rtx)) == REG)
+ 		    {
+ 		      rinfo[ REGNO (SET_DEST (cur_rtx))].insn_set = NULL;
+ 		      for (i = 0; i < cur_max_reg; i++)
+ 		        {
+ 		          if (rinfo[i].insn_set
+ 			      && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
+ 			             SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			    )
+ 			    { /* Current value of reg dest overwritten */
+ 			      rinfo[i].insn_set = NULL;
+ 			    }
+ 		          if (rinfo[i].corresp_mem 
+ 		              && reg_overlap_mentioned_p (SET_DEST (cur_rtx), 
+ 		                   rinfo[i].corresp_mem))
+ 			    { /* Not the same memory address anymore.  */
+ 			      rinfo[i].corresp_mem = NULL;
+ 			    }
+ 		        }
+ 		    }
+ 	          else if ((GET_CODE (cur_rtx) == SET || GET_CODE (cur_rtx) == CLOBBER)
+ 		          && GET_CODE (SET_DEST (cur_rtx)) == MEM
+ 	                  && GET_CODE (dest) == MEM && !only_symref_plus_reg 
+ 		          && flag_replace_mem)
+ 		    {
+ 		      dest = SET_DEST (cur_rtx);
+ 		      for (i = 0; i < cur_max_reg; i++)
+ 		        {
+ 		          if (rinfo[i].corresp_mem 
+ 			      && true_dependence (dest, rinfo[i].corresp_mem))
+ 			    { /* Memory address maybe overwritten.  */
+ 			      rinfo[i].corresp_mem = NULL;
+ 			    }
+ 		        }
+ 		    }
+ 		  else if (!(GET_CODE (cur_rtx) == SET  
+ 		       || GET_CODE (cur_rtx) == CLOBBER
+ 		       || GET_CODE (cur_rtx) == USE))
+ 	            bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 		}
+ 	    }
+ 	  else if (GET_CODE (PATTERN (insn)) == SET)
+ 	    {
+ 	      dest = SET_DEST (PATTERN (insn));
+ 	      if (GET_CODE (SET_SRC (PATTERN (insn))) != REG)
+ 		{
+ 		  header = NULL;
+ 		  storage2 = (char *) obstack_alloc (&momentary_obstack, 0);
+ 		  find_regs_mentioned (SET_SRC (PATTERN (insn)), &header, 0);
+ 		  a_reg_used = header;
+ 		  while (a_reg_used)
+ 		    {
+ 		      undobuf.num_undo = 0;
+ 		      undobuf.storage = (char *) oballoc (0);
+ 		      if (((a_reg_used->in_mem || !only_symref_plus_reg) 
+ 			   && rinfo[REGNO (a_reg_used->reg)].insn_set 
+ 			   && rinfo[REGNO (a_reg_used->reg)].replace_reg == 0 
+ 			   && (!only_symref_plus_reg 
+ 			       || SYMREF_PLUS_REG (rinfo[REGNO (a_reg_used->reg)].insn_set))) 
+ 			  || (rinfo[REGNO (a_reg_used->reg)].corresp_mem 
+ 			   && rinfo[REGNO (a_reg_used->reg)].insn_set 
+ 			   && rinfo[REGNO (a_reg_used->reg)].replace_reg == 1 
+ 			   && rinfo[REGNO (a_reg_used->reg)].do_replace == 1 
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ 			  && !((GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_EXTEND 
+ 		      || GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE)
+ 		      && (IS_STACK_MODE (SFmode) || IS_STACK_MODE (DFmode)))
+ 			   
+ #endif
+ #endif
+ 			   && !only_symref_plus_reg && flag_replace_stack_mem)
+ 			)
+ 			{ /* Try to replace the register with it's current
+ 		              value.  */
+ 			  replace_reg (SET_SRC (PATTERN (insn)),
+ 				       &SET_SRC (PATTERN (insn)),
+ 				       a_reg_used->reg,
+ 				       &(rinfo[REGNO (a_reg_used->reg)]));
+ 			  if ((insn_code_num = recog (PATTERN (insn), insn, 0)) < 0)
+ 			    {
+ 			      recog_ok = 0;
+ 			      try_to_make_good (SET_SRC (PATTERN (insn)));
+ 			    }
+ 			  else
+ 			    {
+ 			      recog_ok = 1;
+ 			    }
+ 			  if (recog_ok 
+ 			      || (insn_code_num = recog (PATTERN (insn), insn, 0)) >= 0)
+ 			    {
+ 			      INSN_CODE (insn) = insn_code_num;
+ 			      /* canonicalize */
+ 			      if (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
+ 				  && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == MULT 
+ 				  && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG)
+ 				{
+ 				  tmp_rtx = XEXP (SET_SRC (PATTERN (insn)), 0);
+ 				  XEXP (SET_SRC (PATTERN (insn)), 0) 
+ 				    = XEXP (SET_SRC (PATTERN (insn)), 1);
+ 				  XEXP (SET_SRC (PATTERN (insn)), 1) = tmp_rtx;
+ 				}
+ 			    }
+ 			  else
+ 			    {
+ 			      loop_undo_all ();
+ 			    }
+ 			}
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ 		      if (IS_STACK_MODE (GET_MODE (a_reg_used->reg)))
+ 			{
+ 			  rinfo[REGNO (a_reg_used->reg)].do_replace = 1;
+ 			}
+ #endif
+ #endif
+ 		      a_reg_used = a_reg_used->next;
+ 		    }
+ 		  if (header != NULL)
+ 		    {
+ 		      obstack_free (&momentary_obstack, storage2);
+ 		    }
+ 		  if (!only_symref_plus_reg && flag_replace_mem)
+ 		    replace_mems (insn, SET_SRC (PATTERN (insn)));
+ 		}
+ 	      src = SET_SRC (PATTERN (insn));
+ 	      if (GET_CODE (dest) != REG)
+ 		{
+ 		  header = NULL;
+ 		  storage2 = (char *) obstack_alloc (&momentary_obstack, 0);
+ 		  find_regs_mentioned (SET_DEST (PATTERN (insn)), &header, 0);
+ 		  a_reg_used = header;
+ 		  while (a_reg_used)
+ 		    {
+ 		      undobuf.num_undo = 0;
+ 		      undobuf.storage = (char *) oballoc (0);
+ 		      if (a_reg_used->in_mem 
+ 			  && rinfo[REGNO (a_reg_used->reg)].insn_set 
+ 			  && (!only_symref_plus_reg 
+ 			   || SYMREF_PLUS_REG (rinfo[REGNO (a_reg_used->reg)].insn_set))
+ 			)
+ 			{ /* Try to replace the register with it's current
+ 		             value.  */
+ 			  replace_reg (SET_DEST (PATTERN (insn)),
+ 				       &SET_DEST (PATTERN (insn)),
+ 				       a_reg_used->reg,
+ 				       &(rinfo[REGNO (a_reg_used->reg)]));
+ 
+ 			  if (recog (PATTERN (insn), insn, 0) < 0)
+ 			    {
+ 			      recog_ok = 0;
+ 			      try_to_make_good (SET_DEST (PATTERN (insn)));
+ 			    }
+ 			  else
+ 			    {
+ 			      recog_ok = 1;
+ 			    }
+ 			  if (recog_ok 
+ 			      || recog (PATTERN (insn), insn, 0) >= 0)
+ 			    {
+ 			      ;
+ 			    }
+ 			  else
+ 			    {
+ 			      loop_undo_all ();
+ 			    }
+ 			}
+ 		      a_reg_used = a_reg_used->next;
+ 		    }
+ 		  if (header != NULL)
+ 		    {
+ 		      obstack_free (&momentary_obstack, storage2);
+ 		    }
+ 		  if (!only_symref_plus_reg 
+ 		      && GET_CODE (src) == REG && GET_CODE (dest) == MEM 
+ 		      && !MEM_VOLATILE_P (dest) 
+ 		      && GET_CODE (XEXP (dest, 0)) != PRE_DEC 
+ 		      && GET_CODE (XEXP (dest, 0)) != PRE_INC
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ 		      && !(IS_STACK_MODE (GET_MODE (src)))
+ #endif
+ #endif
+ 		    )
+ 		    {
+ 		      rinfo[REGNO (src)].corresp_mem = dest;
+ 		      rinfo[REGNO (src)].reg = src;
+ 		      rinfo[REGNO (src)].replace_reg = 0;
+ 		    }
+ 		}
+ 	      if (GET_CODE (dest) == MEM && !only_symref_plus_reg 
+ 		  && flag_replace_mem)
+ 		{
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].corresp_mem && !(GET_CODE (src) == REG && i == REGNO (src)) 
+ 			  && true_dependence (dest, rinfo[i].corresp_mem))
+ 			{ /* Memory address maybe overwritten.  */
+ 			  rinfo[i].corresp_mem = NULL;
+ 			}
+ 		    }
+ 		}
+ 	      if (GET_CODE (dest) == REG)
+ 		{
+ 		  for (i = 0; i < cur_max_reg; i++)
+ 		    {
+ 		      if (rinfo[i].insn_set 
+ 			  && reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (rinfo[i].insn_set)))
+ 			)
+ 			{ /* Current value of reg dest overwritten.  */
+ 			  rinfo[i].insn_set = NULL;
+ 			}
+ 		      if (rinfo[i].corresp_mem 
+ 		          && reg_overlap_mentioned_p (dest, rinfo[i].corresp_mem))
+ 			{ /* Not the same memory address anymore.  */
+ 			  rinfo[i].corresp_mem = NULL;
+ 			}
+ 		    }
+ 		  rinfo[REGNO (dest)].corresp_mem = NULL;
+ 		  if (reg_overlap_mentioned_p (dest, SET_SRC (PATTERN (insn))))
+ 		    {
+ 		      rinfo[REGNO (dest)].insn_set = NULL;
+ 		    }
+ 		  else
+ 		    {
+ 		      if ((GET_CODE (SET_SRC (PATTERN (insn))) == ASHIFT 
+ 		           && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG 
+ 			   && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT) 
+ 			   || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
+ 		               && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG 
+ 			       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == SYMBOL_REF) 
+ 			   || (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
+ 			       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT 
+ 			       && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG 
+ 			       && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) == CONST_INT 
+ 			       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 			)
+ 			{ /* These are the patterns of interest.  */
+ 			  rinfo[REGNO (dest)].insn_set = insn;
+ 			}
+ 		      else
+ 			{
+ 			  rinfo[REGNO (dest)].insn_set = NULL;
+ 			}
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ 		      if (IS_STACK_MODE (GET_MODE (dest)) 
+ 			      && ((GET_CODE (src) == MEM 
+ 			           && !MEM_VOLATILE_P (src)) 
+ 		               || ((IS_STACK_MODE (SFmode) || IS_STACK_MODE (DFmode)) 
+ 		                    && (GET_CODE (src) == FLOAT_EXTEND 
+ 			                    || GET_CODE (src) == FLOAT_TRUNCATE) 
+ 		          && GET_CODE (XEXP (src, 0)) == MEM 
+ 		          && !MEM_VOLATILE_P (XEXP (src, 0))))
+ 		          && flag_replace_stack_mem)
+ 			{
+ 			  rinfo[REGNO (dest)].corresp_mem = src;
+ 			  rinfo[REGNO (dest)].reg = dest;
+ 			  rinfo[REGNO (dest)].insn_set = insn;
+ 			  rinfo[REGNO (dest)].replace_reg = 1;
+ 			  rinfo[REGNO (dest)].do_replace = 0;
+ 			}
+ #endif
+ #endif
+ 		    }
+ 		}
+ 	    }
+ 	  else if (GET_CODE (PATTERN (insn)) != USE)
+ 	    {
+ 	      bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  bzero (rinfo, cur_max_reg * sizeof (struct regopt_info));
+ 	  break;
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+ }
+ 
+ void
+ loop_undo_all ()
+ {
+   register int i;
+   if (undobuf.num_undo > MAX_UNDO)
+     undobuf.num_undo = MAX_UNDO;
+   for (i = undobuf.num_undo - 1; i >= 0; i--)
+     *undobuf.undo[i].where = undobuf.undo[i].old_contents;
+ 
+   obfree (undobuf.storage);
+   undobuf.num_undo = 0;
+ }
+ 
+ /* Replace in pat of insn each MEM with a corresponding reg if one exists.  */
+ static
+ rtx 
+ replace_mems (insn, pat)
+      rtx insn, pat;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+     case REG:
+       return pat;
+ 
+ 
+     }
+ 
+   if (GET_CODE (pat) == MEM)
+     {
+       for (i = 0; i < mem_max_reg_num; i++)
+ 	{
+ 	  if (rinfo[i].corresp_mem && rinfo[i].replace_reg == 0 
+ 	      && rtx_equal_p (rinfo[i].corresp_mem, pat))
+ 	    {
+ 	      return (rinfo[i].reg);
+ 	    }
+ 	}
+     }
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       XEXP (pat, i) = replace_mems (insn, XEXP (pat, i));
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  XVECEXP (pat, i, j) 
+ 	    = replace_mems (insn, XVECEXP (pat, i, j));
+       }
+   return pat;
+ }
+ 
+ 
+ /* Replace in orig each occurrence of reg_rplc with the value
+    described by *rptr.  The location in orig of reg_rplc is where.  
+ */
+ static void
+ replace_reg (orig, where, reg_rplc, rptr)
+      register rtx orig, reg_rplc;
+      rtx *where;
+      struct regopt_info *rptr;
+ {
+   rtx non_biv_operand, ret_rtx;
+   register int i, j;
+   register RTX_CODE code;
+   register char *fmt;
+ 
+   code = GET_CODE (orig);
+ 
+   switch (code)
+     {
+     case REG:
+       if (rtx_equal_p (orig, reg_rplc))
+ 	{
+ 	  if (GET_CODE (SET_SRC (PATTERN (rptr->insn_set))) == ASHIFT 
+ 	      && GET_CODE (XEXP (SET_SRC (PATTERN (rptr->insn_set)), 1)) == CONST_INT
+ 	    )
+ 	    {
+ 	      LOOP_SUBST (where,
+ 	      (gen_rtx (MULT, GET_MODE (SET_SRC (PATTERN (rptr->insn_set))),
+ 			XEXP (SET_SRC (PATTERN (rptr->insn_set)), 0),
+ 			gen_rtx (CONST_INT, 0,
+ 				 two_to_power (INTVAL (XEXP (SET_SRC (PATTERN (rptr->insn_set)), 1)))))));
+ 	    }
+ 	  else
+ 	    {
+ 	      LOOP_SUBST (where, (SET_SRC (PATTERN (rptr->insn_set))));
+ 	    }
+ 	}
+       break;
+ 
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+     case PC:
+     case CC0:
+       return;
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       replace_reg (XEXP (orig, i), &XEXP (orig, i), reg_rplc, rptr);
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (orig, i); j++)
+ 	  replace_reg (XVECEXP (orig, i, j), &XVECEXP (orig, i, j), reg_rplc, rptr);
+       }
+ }
+ 
+ 
+ static int
+ two_to_power (x)
+      int x;
+ {
+   int retval, i;
+ 
+   retval = 1;
+   for (i = 0; i < x; i++)
+     retval *= 2;
+   return (retval);
+ }
+ 
+ 
+ /* Return 1 iff insn p jumps backward to a label that is located
+    between loop_start and p,
+    if strict==1 we also require that any jumps between the target label and
+    p jump to labels that are between the target label and p.  */
+ static int
+ jumps_back_in_loop (p, loop_start, use1, strict)
+      rtx p, loop_start;
+      int use1;		/* If 1 then we require each label within to be accessed only once */
+      int strict;
+ {
+   rtx insn, target, last_jump_found;
+   int jumps_found, labels_found;
+ 
+   if (!flag_jump_back)
+     return (0);
+   target = JUMP_LABEL (p);
+   insn = PREV_INSN (p);
+   jumps_found = 0;
+   labels_found = 0;
+   while (insn != target && insn != loop_start)
+     {
+       if (GET_CODE (insn) == JUMP_INSN)
+ 	{
+ 	  jumps_found++;
+ 	}
+       else if (GET_CODE (insn) == CODE_LABEL)
+ 	{
+ 	  if (use1 && LABEL_NUSES (insn) != 1)
+ 	    {
+ 	      return (0);
+ 	    }
+ 	  labels_found++;
+ 	}
+ 
+       insn = PREV_INSN (insn);
+     }
+   if (insn != target)
+     {
+       return (0);
+     }
+   else
+     {
+       if (use1 && jumps_found != labels_found)
+ 	{
+ 	  return (0);
+ 	}
+       if (jumps_found == 0 || strict == 0)
+ 	{
+ 	  return (1);
+ 	}
+       else
+ 	{ /* Must check each jump to see that it jumps to label
+ 	     between target and p.  */
+ 	  last_jump_found = target;
+ 	  while (jumps_found)
+ 	    {
+ 	      /* Find the next jump.  */
+ 	      insn = NEXT_INSN (last_jump_found);
+ 	      while (GET_CODE (insn) != JUMP_INSN)
+ 		{
+ 		  insn = NEXT_INSN (insn);
+ 		}
+ 	      last_jump_found = insn;
+ 	      /* Now find the target. */
+ 	      while (insn != p && insn != JUMP_LABEL (last_jump_found))
+ 		{ /* Search forward.  */
+ 		  insn = NEXT_INSN (insn);
+ 		}
+ 	      if (insn == JUMP_LABEL (last_jump_found) 
+ 		  && (!use1 || LABEL_NUSES (JUMP_LABEL (last_jump_found)) == 1)
+ 		)
+ 		{
+ 		  jumps_found--;
+ 		}
+ 	      else
+ 		{
+ 		  while (insn != loop_start && insn != JUMP_LABEL (last_jump_found))
+ 		    { /* Search backwards. */
+ 		      insn = PREV_INSN (insn);
+ 		    }
+ 		  if (insn == JUMP_LABEL (last_jump_found) 
+ 		      && (!use1 || LABEL_NUSES (JUMP_LABEL (last_jump_found)) == 1)
+ 		    )
+ 		    {
+ 		      jumps_found--;
+ 		    }
+ 		  else
+ 		    {
+ 		      break;
+ 		    }
+ 		}
+ 	    }
+ 	  return (jumps_found == 0);
+ 	}
+     }
+ }
+ 
+ 
+ struct propogate_cand
+ {
+   rtx srcpat;
+   rtx add_reg0;
+   rtx add_reg1;
+   rtx mul_reg;
+   rtx reg;
+   int mul_val;
+   char cand_type;
+ };
+ 
+ struct unroll_combine_cand
+ {
+   rtx reg;
+   struct unroll_combine_cand *next;
+ };
+ 
+ #define COPY 1
+ #define GIV 2
+ 
+ /* Try to propogate copies into loop as follows:
+    If before the loop we have
+    regx <- regy
+    and in the loop regx is only used, then replace each use of regx
+    in the loop with regy
+ */
+ static
+ loop_copy_propogate (loop_start, loop_end)
+      rtx loop_start, loop_end;
+ {
+   struct propogate_cand *copy_candidates, *possible_giv_candidate;
+   char *regs_set, dummyc;
+   rtx insn, loop_label, loop_jump, dest, src, *split_giv_src;
+   int num_copy_candidates, num_giv_candidates,
+     stop_looking, cur_max_regnum, i, dummyi, num_unroll_candidates;
+   struct unroll_combine_cand **unroll_cands, *an_unroll_cand;
+ 
+   cur_max_regnum = max_reg_num () + 1;
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "copy prop from %d to %d\n",
+ 	       INSN_UID (loop_start), INSN_UID (loop_end));
+     }
+   copy_candidates = (struct propogate_cand *)
+     alloca (cur_max_regnum * sizeof (struct propogate_cand));
+   bzero (copy_candidates, (cur_max_regnum * sizeof (struct propogate_cand)));
+   regs_set = (char *) alloca (cur_max_regnum);
+   bzero (regs_set, cur_max_regnum);
+   n_times_set = (short *) alloca (cur_max_regnum * sizeof (short));
+   bzero (n_times_set, cur_max_regnum * sizeof (short));
+   may_not_optimize = (char *) alloca (cur_max_regnum);	/* not used */
+   if (flag_unroll_loops)
+     {
+       unroll_cands 
+ 	= (struct unroll_combine_cand **)
+ 	alloca (cur_max_regnum * sizeof (struct unroll_combine_cand *));
+       bzero (unroll_cands, cur_max_regnum * sizeof (struct unroll_combine_cand *));
+       split_giv_src = (rtx *) alloca (cur_max_regnum * sizeof (rtx));
+       bzero (split_giv_src, cur_max_regnum * sizeof (rtx));
+     }
+   /* First check that the label that is the start of the loop
+      is only jumped to from within the loop - if not return
+   */
+   insn = loop_start;
+   while (insn && GET_CODE (insn) != CODE_LABEL)
+     {
+       insn = NEXT_INSN (insn);
+     }
+   loop_label = insn;
+   insn = loop_end;
+   while (insn && GET_CODE (insn) != JUMP_INSN)
+     {
+       insn = PREV_INSN (insn);
+     }
+   loop_jump = insn;
+   if (!loop_label || !loop_jump 
+       || (JUMP_LABEL (loop_jump) != loop_label) 
+       || (LABEL_NUSES (JUMP_LABEL (loop_jump)) != 1)
+     )
+     {
+       return;
+     }
+   /* Compute n_times_set */
+   count_loop_regs_set (loop_start, loop_end, may_not_optimize, NULL,
+ 		       &dummyi, cur_max_regnum);
+ 
+   /* Look backwards from loop_start until a label barier or
+      uncoditional jump is reached,
+      searching for insns of the form regx <- regy and regx
+      NOT set in loop  - these are candidates for copy propogation.  
+      Also search for registers that are set rega <- regb*C + regd
+      - rega is a candidate for inter loop giv combination.  
+   */
+   insn = loop_start;
+   num_copy_candidates = 0;
+   num_giv_candidates = 0;
+   num_unroll_candidates = 0;
+   stop_looking = 0;
+   possible_giv_candidate = NULL;
+   while (insn && !stop_looking)
+     {
+       switch (GET_CODE (insn))
+ 	{
+ 	case NOTE:
+ 	  break;
+ 
+ 	case JUMP_INSN:
+ 	  if (SET_DEST (PATTERN (insn)) == pc_rtx
+ 	      && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF)
+ 	    {
+ 	      stop_looking = 1;
+ 	    }
+ 	  break;
+ 
+ 	case CODE_LABEL:
+ 	case BARRIER:
+ 	  stop_looking = 1;
+ 	  break;
+ 
+ 	case INSN:
+ 	  if (GET_CODE (PATTERN (insn)) != SET)
+ 	    {
+ 	      stop_looking = 1;
+ 	    }
+ 	  else
+ 	    {
+ 	      dest = SET_DEST (PATTERN (insn));
+ 	      src = SET_SRC (PATTERN (insn));
+ 	      if (GET_CODE (dest) == REG)
+ 		{
+ 		  if (flag_unroll_loops && dest != cc0_rtx 
+ 		      && REGNO (dest) >= FIRST_PSEUDO_REGISTER 
+ 		      && dest != pc_rtx && regs_set[REGNO (dest)] == 0 
+ 		      && GET_CODE (src) == REG && regs_set[REGNO (src)] == 0
+ 		      && REGNO (src) >= FIRST_PSEUDO_REGISTER )
+ 		    { /* The dest may be a split giv which we want
+                          to combine */
+ 		      if (split_giv_src[REGNO (dest)] == NULL)
+ 			{
+ 			  split_giv_src[REGNO (dest)] = src;
+ 			  an_unroll_cand 
+ 			    = (struct unroll_combine_cand *)
+ 			    alloca (sizeof (struct unroll_combine_cand));
+ 			  an_unroll_cand->reg = dest;
+ 			  an_unroll_cand->next = unroll_cands[REGNO (src)];
+ 			  unroll_cands[REGNO (src)] = an_unroll_cand;
+ 			  num_unroll_candidates++;
+ 			}
+ 		      else
+ 			{
+ 			  split_giv_src[REGNO (dest)] = (rtx) - 1;
+ 			}
+ 		    }
+ 
+ 		  if (dest != cc0_rtx && dest != pc_rtx 
+ 		      && REGNO (dest) >= FIRST_PSEUDO_REGISTER 
+ 		      && regs_set[REGNO (dest)] == 0)
+ 		    {
+ 		      if (GET_CODE (src) == REG 
+ 			  && REGNO (src) >= FIRST_PSEUDO_REGISTER 
+ 			  && n_times_set[REGNO (src)] == 0 
+ 			  && regs_set[REGNO (src)] == 0)
+ 			{
+ 			  if (n_times_set[REGNO (dest)] == 0)
+ 			    {
+ 			      num_copy_candidates++;
+ 			      copy_candidates[REGNO (dest)].srcpat = src;
+ 			      copy_candidates[REGNO (dest)].cand_type = COPY;
+ 			    }
+ 			}
+ 		      else
+ 			{
+ 			  if (GET_CODE (src) == PLUS 
+ 			      && GET_CODE (XEXP (src, 0)) == REG 
+ 			      && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER 
+ 			      && GET_CODE (XEXP (src, 1)) == REG 
+ 			      && REGNO (XEXP (src, 1)) >= FIRST_PSEUDO_REGISTER 
+ 			      && regs_set[REGNO (XEXP (src, 0))] == 0 
+ 			      && regs_set[REGNO (XEXP (src, 1))] == 0 
+ 			      && n_times_set[REGNO (XEXP (src, 1))] == 0 
+ 			      && copy_candidates[REGNO (dest)].srcpat == NULL 
+ 			      && copy_candidates[REGNO (dest)].add_reg0 == NULL)
+ 			    {
+ 			      copy_candidates[REGNO (dest)].add_reg0 
+ 				= XEXP (src, 0);
+ 			      copy_candidates[REGNO (dest)].add_reg1 
+ 				= XEXP (src, 1);
+ 			      possible_giv_candidate 
+ 				= &copy_candidates[REGNO (dest)];
+ 			      possible_giv_candidate->reg = dest;
+ 			    }
+ 			  else if (GET_CODE (src) == ASHIFT 
+ 				   && GET_CODE (XEXP (src, 0)) == REG 
+ 				   && GET_CODE (XEXP (src, 1)) == CONST_INT 
+ 				   && regs_set[REGNO (XEXP (src, 0))] == 0 
+ 				   && possible_giv_candidate 
+ 				   && possible_giv_candidate->mul_reg == NULL 
+ 				   && rtx_equal_p (dest, possible_giv_candidate->add_reg0)
+ 			    )
+ 			    {
+ 			      possible_giv_candidate->mul_reg = XEXP (src, 0);
+ 			      possible_giv_candidate->mul_val 
+ 				= two_to_power (INTVAL (XEXP (src, 1)));
+ 			      possible_giv_candidate->cand_type = GIV;
+ 			      num_giv_candidates++;
+ 			    }
+ 			}
+ 		    }
+ 		  regs_set[REGNO (dest)] = 1;
+ 		}
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  stop_looking = 1;
+ 	  break;
+ 	}
+       insn = PREV_INSN (insn);
+     }
+   if (num_copy_candidates != 0)
+     {
+       /* Now for each candidate do the replacement */
+       do_replace (loop_start, loop_end, copy_candidates);
+     }
+   if (num_unroll_candidates != 0)
+     {
+       try_unroll_propogation (loop_start, loop_end, unroll_cands, split_giv_src);
+     }
+ }
+ 
+ /*
+   Each occurence of a copy_candidate in an insn between loop_start
+   and loop_end is replaced by the corresponding register.  
+ */
+ static
+ do_replace (loop_start, loop_end, copy_candidates)
+      rtx loop_start, loop_end;
+      struct propogate_cand *copy_candidates;
+ {
+   rtx insn, subst_cands ();
+ 
+   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  subst_cands (insn, PATTERN (insn), copy_candidates);
+ 	}
+     }
+ }
+ 
+ 
+ /* Each register in pat which is a copy_candidate of type COPY is replaced with
+    it's copy from outside the loop.  
+ */
+ static
+ rtx 
+ subst_cands (insn, pat, copy_candidates)
+      rtx insn, pat;
+      struct propogate_cand *copy_candidates;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return pat;
+ 
+     case REG:
+       {
+ 	register int regno = REGNO (pat);
+ 
+ 	if (copy_candidates[regno].srcpat 
+ 	    && copy_candidates[regno].cand_type == COPY)
+ 	  {
+ 	    if (loop_dump_stream)
+ 	      {
+ 		fprintf (loop_dump_stream, "replacing reg%d with reg%d in insn %d\n",
+ 			 regno, REGNO (copy_candidates[regno].srcpat), INSN_UID (insn));
+ 	      }
+ 	    return (copy_candidates[regno].srcpat);
+ 	  }
+       }
+       return pat;
+ 
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       XEXP (pat, i) = subst_cands (insn, XEXP (pat, i), copy_candidates);
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  XVECEXP (pat, i, j) 
+ 	    = subst_cands (insn, XVECEXP (pat, i, j), copy_candidates);
+       }
+   return pat;
+ }
+ 
+ struct reg_incs
+ {
+   int inc_val;
+   char invalid;
+ };
+ 
+ /* Try to combine split givs from unrolling into one giv to decrease
+    register pressure and increase scheduling possiblities
+ */
+ static
+ try_unroll_propogation (loop_start, loop_end, unroll_cands, split_giv_src)
+      rtx loop_start, loop_end;
+      struct unroll_combine_cand **unroll_cands;
+      rtx *split_giv_src;
+ {
+   rtx insn, src, dest, ninsn, nsrc, ndest, unroll_subst_cands ();
+   struct reg_incs *reg_inc;
+   int i, cur_max_regnum, found;
+ 
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, " unroll propogate from %d to %d\n",
+ 	       INSN_UID (loop_start), INSN_UID (loop_end));
+     }
+   cur_max_regnum = max_reg_num () + 1;
+   reg_inc 
+     = (struct reg_incs *) alloca (cur_max_regnum * (sizeof (struct reg_incs)));
+   bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
+   insn = NEXT_INSN (loop_start);
+   while (insn != loop_end)
+     {
+       switch (GET_CODE (insn))
+ 	{
+ 
+ 	case NOTE:
+ 	  break;
+ 
+ 	case JUMP_INSN:
+ 	case CODE_LABEL:
+ 	case BARRIER:
+ 	  unroll_consistancy_maintained (cur_max_regnum, unroll_cands,
+ 					 reg_inc, insn, split_giv_src);
+ 	  /* forget everything */
+ 	  bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
+ 	  break;
+ 
+ 	case INSN:
+ 	  if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	    {
+ 	      return;
+ 	    }
+ 	  if (GET_CODE (PATTERN (insn)) != SET)
+ 	    {
+ 	      return;
+ 	    }
+ 	  dest = SET_DEST (PATTERN (insn));
+ 	  if (GET_CODE (dest) == REG)
+ 	    {
+ 	      if (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
+ 		  && rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0), dest) 
+ 		  && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 		{ /* reg incremented by constatnt */
+ 		  reg_inc[REGNO (dest)].inc_val 
+ 		    += INTVAL (XEXP (SET_SRC (PATTERN (insn)), 1));
+ 		}
+ 	      else
+ 		{
+ 		  reg_inc[REGNO (dest)].invalid = 1;
+ 		}
+ 	    }
+ 	  break;
+ 
+ 	default:
+ 	  return;
+ 	  break;
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   insn = NEXT_INSN (loop_start);
+   /* Combine each valid unroll candidate */
+   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  unroll_subst_cands (insn, PATTERN (insn), unroll_cands, split_giv_src);
+ 	}
+     }
+ }
+ 
+ 
+ /* Try to combine split givs from unrolling into one giv to decrease
+    register pressure and increase scheduling possiblities
+ */
+ static
+ rtx 
+ unroll_subst_cands (insn, pat, unroll_cands, split_giv_src)
+      rtx insn, pat;
+      struct unroll_combine_cand **unroll_cands;
+      rtx *split_giv_src;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+ 
+   if (GET_CODE (pat) == REG && pat == SET_DEST (PATTERN (insn)))
+     {
+       return (pat);
+     }
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return pat;
+ 
+     case REG:
+       {
+ 	register int regno = REGNO (pat);
+ 
+ 	if (split_giv_src[regno] && split_giv_src[regno] != (rtx) - 1 
+ 	    && unroll_cands[REGNO (split_giv_src[regno])])
+ 	  {
+ 	    if (loop_dump_stream)
+ 	      {
+ 		fprintf (loop_dump_stream, "   replacing reg%d with reg%d in insn %d\n",
+ 		      regno, REGNO (split_giv_src[regno]), INSN_UID (insn));
+ 	      }
+ 	    return (split_giv_src[regno]);
+ 	  }
+       }
+       return pat;
+ 
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       XEXP (pat, i) 
+ 	= unroll_subst_cands (insn, XEXP (pat, i), unroll_cands, split_giv_src);
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  XVECEXP (pat, i, j) 
+ 	    = unroll_subst_cands (insn, XVECEXP (pat, i, j), unroll_cands,
+ 			  split_giv_src);
+       }
+   return pat;
+ }
+ 
+ /* Check that spilt givs remain consistant */
+ static
+ unroll_consistancy_maintained (cur_max_regnum, unroll_cands, reg_inc, insn,
+ 			       split_giv_src)
+      int cur_max_regnum;
+      struct unroll_combine_cand **unroll_cands;
+      struct reg_incs *reg_inc;
+      rtx *split_giv_src;
+      rtx insn;
+ {
+   int i;
+   struct unroll_combine_cand *an_unroll_cand;
+ 
+   for (i = 0; i < cur_max_regnum; i++)
+     {
+       if (unroll_cands[i])
+ 	{
+ 	  if (reg_inc[i].invalid)
+ 	    {
+ 	      unroll_cands[i] = NULL;
+ 	    }
+ 	  else
+ 	    { /* Check each candidate to see that it was incremented
+                  by same amount.  */
+ 	      an_unroll_cand = unroll_cands[i];
+ 	      while (an_unroll_cand)
+ 		{
+ 		  if (reg_inc[REGNO (an_unroll_cand->reg)].invalid 
+ 		      || reg_inc[REGNO (an_unroll_cand->reg)].inc_val !=
+ 		      reg_inc[i].inc_val)
+ 		    {
+ 		      split_giv_src[REGNO (an_unroll_cand->reg)] = (rtx) - 1;
+ 		    }
+ 		  an_unroll_cand = an_unroll_cand->next;
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ 
+ #ifdef STORE_NOT_SET_CC0
+ #ifdef STACK_REGS
+ /* do_spl is called after reload because the reloader decides to spill
+    fp regs, for no appareant reason, if it is done before.
+ */
+ void
+ do_spl (f)
+      /* f is the first instruction of a chain of insns for one function */
+      rtx f;
+ {
+   register rtx insn;
+   register int i;
+   rtx end;
+   rtx last_insn;
+ 
+ #ifndef HAVE_cc0
+   return;
+ #endif
+ 
+   /* Count the number of loops. */
+ 
+   max_loop_num = 0;
+   for (insn = f; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == NOTE
+ 	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ 	max_loop_num++;
+     }
+ 
+   /* Don't waste time if no loops.  */
+   if (max_loop_num == 0)
+     return;
+   doing_spl = 1;
+   /* Get size to use for tables indexed by uids.
+      Leave some space for labels allocated by find_and_verify_loops.  */
+   max_uid_for_loop = get_max_uid () + 1 + max_loop_num * 4;
+ 
+   uid_luid = (int *) alloca (max_uid_for_loop * sizeof (int));
+   uid_loop_num = (int *) alloca (max_uid_for_loop * sizeof (int));
+ 
+   bzero (uid_luid, max_uid_for_loop * sizeof (int));
+   bzero (uid_loop_num, max_uid_for_loop * sizeof (int));
+ 
+   /* Allocate tables for recording each loop.  We set each entry, so they need
+      not be zeroed.  */
+   loop_number_loop_starts = (rtx *) alloca (max_loop_num * sizeof (rtx));
+   loop_number_loop_ends = (rtx *) alloca (max_loop_num * sizeof (rtx));
+   loop_outer_loop = (int *) alloca (max_loop_num * sizeof (int));
+   loop_invalid = (char *) alloca (max_loop_num * sizeof (char));
+   loop_number_exit_labels = (rtx *) alloca (max_loop_num * sizeof (rtx));
+ 
+   /* Find and spl each loop.
+      First, find them, and record them in order of their beginnings.  */
+   find_and_verify_loops (f);
+   for (i = max_loop_num - 1; i >= 0; i--)
+     {
+       if (loop_number_loop_ends[i])
+ 	loop_spl (loop_number_loop_starts[i], loop_number_loop_ends[i], i, 1);
+     }
+   doing_spl = 0;
+ }
+ 
+ /*
+    A mini software pipelining - consists of two steps
+    1) try to get the floating point store to be the last instruction
+       executed before the jump at the end of loop.
+    2) try to get the jump to be executed before the floating point
+       store by retargeting it to the begining of loop and moving
+       the floating point store to there.  Note that the fall into the
+       loop will be replaced by a jump around this floating point store
+    If do_all is 0 then just do step 1
+ */
+ static
+ loop_spl (loop_start, loop_end, loop_num, do_all)
+      rtx loop_start, loop_end;
+      int loop_num, do_all;
+ {
+   rtx insn, jump_insn, mem_addr, base_reg, index_reg, copy_pat, label_insn,
+     label, p, *index_where, *base_where, pinsn, cc0_insn, where_to_move;
+   struct reg_incs *reg_inc;
+   int cur_max_regnum, scale;
+   char *storage;
+ 
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "loop_spl from %d to %d\n",
+ 	       INSN_UID (loop_start), INSN_UID (loop_end));
+     }
+   cur_max_regnum = max_reg_num () + 1;
+   reg_inc 
+     = (struct reg_incs *) alloca (cur_max_regnum * (sizeof (struct reg_incs)));
+   bzero (reg_inc, cur_max_regnum * (sizeof (struct reg_incs)));
+   insn = PREV_INSN (loop_end);
+   while (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
+ 	 && rtx_equal_p (SET_DEST (PATTERN (insn)), SET_SRC (PATTERN (insn))))
+     {
+       insn = PREV_INSN (insn);
+     }
+   if (GET_CODE (insn) != JUMP_INSN)
+     {
+       
+       return;
+     }
+   jump_insn = insn;
+   insn = PREV_INSN (jump_insn);
+   if (!(GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
+ 	&& SET_DEST (PATTERN (insn)) == cc0_rtx))
+     {
+       
+       return;
+     }
+   cc0_insn = insn;
+   base_reg = NULL;
+   index_reg = NULL;
+   scale = 1;
+   insn = prev_nonnote_insn (insn);
+   while (1)
+     {
+       if (GET_CODE (insn) != INSN)
+ 	{
+ 	  
+ 	  return;
+ 	}
+       if (GET_CODE (PATTERN (insn)) != SET)
+ 	{
+ 	  
+ 	  return;
+ 	}
+       if (GET_CODE (SET_DEST (PATTERN (insn))) == REG 
+ 	  && (GET_CODE (SET_SRC (PATTERN (insn))) == PLUS 
+ 	   || GET_CODE (SET_SRC (PATTERN (insn))) == MINUS) 
+ 	  && rtx_equal_p (SET_DEST (PATTERN (insn)),
+ 		       XEXP (SET_SRC (PATTERN (insn)), 0)) 
+ 	  && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == CONST_INT)
+ 	{
+ 	  reg_inc[REGNO (SET_DEST (PATTERN (insn)))].inc_val 
+ 	    += INTVAL (XEXP (SET_SRC (PATTERN (insn)), 1));
+ 	  if (GET_CODE (SET_SRC (PATTERN (insn))) == MINUS)
+ 	    {
+ 	      reg_inc[REGNO (SET_DEST (PATTERN (insn)))].inc_val *= -1;
+ 	    }
+ 	  insn = prev_nonnote_insn (insn);
+ 	}
+       else
+ 	{
+ 	  break;
+ 	}
+     }
+   if (!(GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET 
+ 	&& (GET_CODE (SET_SRC (PATTERN (insn))) == REG 
+ 	|| (GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE 
+ 	&& GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG) 
+ 	|| (GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_EXTEND 
+ 	&& GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == REG))
+ 	&& GET_CODE (SET_DEST (PATTERN (insn))) == MEM 
+ 	&& (GET_MODE (SET_DEST (PATTERN (insn))) == SFmode 
+ 	|| GET_MODE (SET_DEST (PATTERN (insn))) == DFmode) 
+         && GET_MODE (SET_DEST (PATTERN (insn))) == 
+             GET_MODE (SET_SRC (PATTERN (insn)))
+       )
+     )
+     {
+       
+       return;
+     }
+   /* if previous fp instruction is fld - no gain */
+   pinsn = prev_nonnote_insn (insn);
+   if (INSN_UID (pinsn) < INSN_UID (loop_start))
+     {
+       
+       return;
+     }
+   while (pinsn != loop_start)
+     {
+       if (GET_CODE (pinsn) == JUMP_INSN || GET_CODE (pinsn) == CODE_LABEL 
+ 	  || (GET_CODE (pinsn) == INSN && GET_CODE (PATTERN (pinsn)) == SET 
+ 	   && (GET_MODE (SET_DEST (PATTERN (pinsn))) == SFmode 
+ 	    || GET_MODE (SET_DEST (PATTERN (pinsn))) == DFmode)
+ 	  )
+ 	)
+ 	{
+ 	  break;
+ 	}
+       pinsn = PREV_INSN (pinsn);
+     }
+   if (pinsn == loop_start || GET_CODE (pinsn) == JUMP_INSN 
+       || GET_CODE (pinsn) == CODE_LABEL)
+     {
+       
+       return;
+     }
+   if ((GET_CODE (SET_SRC (PATTERN (pinsn))) == MEM 
+ 	   || GET_CODE (SET_SRC (PATTERN (pinsn))) == CONST_DOUBLE 
+ 	   || GET_CODE (SET_SRC (PATTERN (pinsn))) == REG)
+     )
+     {
+       
+       return;
+     }
+   /* We have found the floating point store insn - now try to move it down */
+   /* Find the registers that are used as bases for the memory access in the
+      insn */
+   storage = (char *) oballoc (0);
+   copy_pat = copy_rtx (PATTERN (insn));
+   mem_addr = XEXP (SET_DEST (copy_pat), 0);
+   if (GET_CODE (mem_addr) == PLUS)
+     {
+       if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
+ 	{
+ 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG 
+ 	      && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == CONST_INT)
+ 	    {
+ 	      index_where = &XEXP (XEXP (mem_addr, 0), 0);
+ 	      index_reg = XEXP (XEXP (mem_addr, 0), 0);
+ 	      scale = INTVAL (XEXP (XEXP (mem_addr, 0), 1));
+ 	    }
+ 	  else
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
+ 	    {
+ 	      base_where = &XEXP (mem_addr, 1);
+ 	      base_reg = XEXP (mem_addr, 1);
+ 	    }
+ 	  else if (GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF 
+ 		   || GET_CODE (XEXP (mem_addr, 1)) == CONST)
+ 	    {
+ 	      ;
+ 	    }
+ 	  else
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	}
+       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
+ 	{
+ 	  /* Take care of non canonicalized expressions */
+ 	  rtx tmp;
+ 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG 
+ 	      && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == MULT)
+ 	    {
+ 	      tmp = XEXP (XEXP (mem_addr, 0), 0);
+ 	      XEXP (XEXP (mem_addr, 0), 0) = XEXP (XEXP (mem_addr, 0), 1);
+ 	      XEXP (XEXP (mem_addr, 0), 1) = tmp;
+ 	    }
+ 
+ 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) != MULT)
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	  if (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == REG 
+ 	      && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT)
+ 	    {
+ 	      index_where = &XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
+ 	      index_reg = XEXP (XEXP (XEXP (mem_addr, 0), 0), 0);
+ 	      scale = INTVAL (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1));
+ 	    }
+ 	  else
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != REG)
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	  base_where = &XEXP (XEXP (mem_addr, 0), 1);
+ 	  base_reg = XEXP (XEXP (mem_addr, 0), 1);
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) == SYMBOL_REF 
+ 	      || GET_CODE (XEXP (mem_addr, 1)) == CONST 
+ 	      || GET_CODE (XEXP (mem_addr, 1)) == CONST_INT)
+ 	    {
+ 	      ;
+ 	    }
+ 	  else
+ 	    {
+ 	      
+ 	      return;
+ 	    }
+ 	}
+       else if (GET_CODE (XEXP (mem_addr, 0)) == REG)
+ 	{
+ 	  base_where = &XEXP (mem_addr, 0);
+ 	  base_reg = XEXP (mem_addr, 0);
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
+ 	    {
+ 	      index_where = &XEXP (mem_addr, 1);
+ 	      index_reg = XEXP (mem_addr, 1);
+ 	    }
+ 	}
+       else
+ 	{
+ 	  
+ 	  return;
+ 	}
+     }
+   else if (GET_CODE (mem_addr) == SYMBOL_REF || GET_CODE (mem_addr) == CONST)
+     {
+       ;
+     }
+   else if (GET_CODE (mem_addr) == REG)
+     {
+       base_reg = mem_addr;
+       base_where = &XEXP (SET_DEST (copy_pat), 0);
+     }
+   else
+     {
+       
+       return;
+     }
+   /* Now we know the base index and scale */
+   if (index_reg && reg_inc[REGNO (index_reg)].inc_val)
+     {
+       *index_where = gen_rtx (PLUS, GET_MODE (index_reg), index_reg,
+ 	   gen_rtx (CONST_INT, 0, reg_inc[REGNO (index_reg)].inc_val * -1));
+     }
+   if (base_reg && reg_inc[REGNO (base_reg)].inc_val)
+     {
+       *base_where = gen_rtx (PLUS, GET_MODE (base_reg), base_reg,
+ 	    gen_rtx (CONST_INT, 0, reg_inc[REGNO (base_reg)].inc_val * -1));
+     }
+ #ifdef REWRITE_ADDRESS
+   if (recog (copy_pat, insn, 0) < 0)
+     {
+       try_to_make_good (SET_DEST (copy_pat));
+     }
+ #endif
+   if (recog (copy_pat, insn, 0) < 0)
+     {
+       obfree (storage);
+       
+       return;
+     }
+   if (do_all == 0)
+     {
+       where_to_move = cc0_insn;
+     }
+   else
+     {
+       where_to_move = jump_insn;
+     }
+   /* Now move the store with it's new pattern */
+   PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+   NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+   NEXT_INSN (insn) = where_to_move;
+   PREV_INSN (insn) = PREV_INSN (where_to_move);
+   NEXT_INSN (PREV_INSN (where_to_move)) = insn;
+   PREV_INSN (where_to_move) = insn;
+   PATTERN (insn) = copy_pat;
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, " moved fp store down\n");
+     }
+   if (do_all == 0)
+     {
+       
+       return;
+     }
+   /* Now move the store again and add a new jump and label */
+   if (loop_invalid[loop_num])
+     {
+       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
+       
+       return;
+     }
+   if (GET_CODE (NEXT_INSN (loop_start)) != CODE_LABEL)
+     {
+       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
+       
+       return;
+     }
+   label_insn = NEXT_INSN (loop_start);
+   if (GET_CODE (SET_SRC (PATTERN (jump_insn))) != IF_THEN_ELSE)
+     {
+       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
+       
+       return;
+     }
+ #if 0
+   if (LABEL_NUSES (label_insn) != 1)
+     {
+       emit_insn_before (gen_rtx (USE, 0, cc0_rtx), insn);
+       
+       return;
+     }
+ #endif
+   /* Make a jump to the old label just before the label*/
+   p = emit_jump_insn_after (gen_jump (label_insn), 
+                             PREV_INSN (label_insn));
+   JUMP_LABEL (p) = label_insn;
+   emit_barrier_after (p);
+   /* Add a new label just before the old one */
+   label = gen_label_rtx ();
+   label_insn = emit_label_after (label, PREV_INSN (label_insn));
+   /* Make the jump at the end of the loop jump to the new lable */
+   if (XEXP (SET_SRC (PATTERN (jump_insn)), 1) == pc_rtx)
+     {
+       XEXP (SET_SRC (PATTERN (jump_insn)), 2)
+         = gen_rtx (LABEL_REF, VOIDmode, label);
+     }
+   else
+     {
+       XEXP (SET_SRC (PATTERN (jump_insn)), 1)
+         = gen_rtx (LABEL_REF, VOIDmode, label);
+     }
+   ++LABEL_NUSES (label_insn);
+   JUMP_LABEL (jump_insn) = label_insn;
+   /* Move the store to just after the new label */
+   PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+   NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+   NEXT_INSN (insn) = NEXT_INSN (label_insn);
+   PREV_INSN (insn) = label_insn;
+   PREV_INSN (NEXT_INSN (label_insn)) = insn;
+   NEXT_INSN (label_insn) = insn;
+   /* Add the store after the jump at the end of the loop */
+   p = emit_insn_after (PATTERN (insn), jump_insn);
+   REG_NOTES (p) = REG_NOTES (insn);
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, " spl successful\n");
+     }
+ }
+ 
+ #endif
+ #endif
+ 
+ /* Element N is first insn in basic block N.
+    This info lasts until we finish compiling the function.  */
+ 
+ extern rtx *basic_block_head;
+ 
+ /* Element N is last insn in basic block N.
+    This info lasts until we finish compiling the function.  */
+ 
+ extern rtx *basic_block_end;
+ 
+ /* Number of basic blocks in the current function.  */
+ 
+ extern int n_basic_blocks;
+ 
+ extern regset *basic_block_live_at_start;
+ 
+ /*        Move spills out of loops if possible i.e.
+           if can find a register in the loop that is
+           alway used to hold a certian spill slot then
+           1) load the spill slot into that register before the
+              loop.
+           2) replace all refernces to the spill slot int the loop with
+              refernces to that register
+           3) if the spill slot was updated in the loop and the pseudo
+              that corresponds to that spill slot is alive at the loop
+              fallout then write that register back to the spill slot
+              at the end of the loop.  NOTE that if the pseudo is
+              alive at any other of the loop exits (if there are any)
+              and the spill slot is updated in the loop then steps
+              1) and 2) are NOT done.  
+           NOTE
+           a) if the spill slot is only loaded into the register once
+              throughout the loop and the spill slot is not updated in
+              the loop then loop_optimize() called from here will
+              probably handle this.  I say probably because maybe_never
+              of scan_loop is rather over cautious since it is set
+              when a jump_insn is encountered but not reset when
+              the corresponding label is encountered.  
+ 
+ 
+           Other optimizations which are done here are trying
+           to push invariants that were spilled back into the loop
+           (see push_load_into_loop()).  
+ 
+           Also a straight line pass over the function is made
+           and whenever a spill slot is loaded into a register
+           if that spill slot is also valid in some register
+           then that spill slot is replaced with that register.  
+           (see peep_spills()).  
+ 
+ */
+ void
+ loop_after_global (f, dumpfile)
+      /* f is the first instruction of a chain of insns for one function */
+      rtx f;
+      FILE *dumpfile;
+ {
+   rtx insn;
+   int i;
+   rtx nonlocal_label_list = nonlocal_label_rtx_list ();
+   register regset tem;
+ 
+   int sav_flag_copy_prop;
+   int sav_flag_jump_back;
+   int sav_flag_compare_elim;
+   int sav_flag_unroll_loops;
+   int sav_flag_strength_reduce;
+ 
+ 
+   sav_flag_copy_prop = flag_copy_prop;
+   sav_flag_jump_back = flag_jump_back;
+   sav_flag_compare_elim = flag_compare_elim;
+   sav_flag_unroll_loops = flag_unroll_loops;
+   sav_flag_strength_reduce = flag_strength_reduce;
+ 
+   flag_copy_prop = 0;
+   flag_jump_back = 0;
+   flag_compare_elim = 0;
+   flag_unroll_loops = 0;
+   flag_strength_reduce = 0;
+ 
+   cur_stack_offset = 0;
+   doing_loop_after_global = 1;
+   loop_optimize (f, dumpfile);
+   doing_loop_after_global = 0;
+   { /* Update basic block start and ends */
+     register RTX_CODE prev_code = JUMP_INSN;
+     register RTX_CODE code;
+     for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
+       {
+ 	code = GET_CODE (insn);
+ 	if (code == CODE_LABEL
+ 	    || (GET_RTX_CLASS (code) == 'i'
+ 		&& (prev_code == JUMP_INSN
+ 		    || (prev_code == CALL_INSN
+ 			&& nonlocal_label_list != 0)
+ 		    || prev_code == BARRIER)))
+ 	  i++;
+ 	if (code != NOTE)
+ 	  prev_code = code;
+       }
+     if (i > n_basic_blocks)
+       {
+         n_basic_blocks = i;
+         basic_block_head = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
+         basic_block_end = (rtx *) oballoc (n_basic_blocks * sizeof (rtx));
+       }
+     n_basic_blocks = i;
+     prev_code = JUMP_INSN;
+     for (insn = f, i = -1; insn; insn = NEXT_INSN (insn))
+       {
+ 	code = GET_CODE (insn);
+ 	/* A basic block starts at label, or after something that can jump.  */
+ 	if (code == CODE_LABEL
+ 	    || (GET_RTX_CLASS (code) == 'i'
+ 		&& (prev_code == JUMP_INSN
+ 		    || (prev_code == CALL_INSN
+ 			&& nonlocal_label_list != 0)
+ 		    || prev_code == BARRIER)))
+ 	  {
+ 	    basic_block_head[++i] = insn;
+ 	    if (i >= n_basic_blocks)
+ 	      {
+ 		abort ();
+ 	      }
+ 	    basic_block_end[i] = insn;
+ 	  }
+ 	else if (GET_RTX_CLASS (code) == 'i')
+ 	  {
+ 	    basic_block_end[i] = insn;
+ 	  }
+ 
+ 	if (code != NOTE
+ 	    && !(prev_code == CALL_INSN && code == INSN
+ 		 && GET_CODE (PATTERN (insn)) == CLOBBER))
+ 	  prev_code = code;
+       }
+   }
+   flag_copy_prop = sav_flag_copy_prop;
+   flag_jump_back = sav_flag_jump_back;
+   flag_compare_elim = sav_flag_compare_elim;
+   flag_unroll_loops = sav_flag_unroll_loops;
+   flag_strength_reduce = sav_flag_strength_reduce;
+ 
+ }
+ 
+ /* x is a spill slot and hence is unaliased
+ */
+ 
+ static int
+ spill_invariant_p (x)
+      register rtx x;
+ {
+   register int i;
+   register enum rtx_code code;
+   register char *fmt;
+   int conditional = 0;
+ 
+   if (x == 0)
+     return 1;
+   code = GET_CODE (x);
+   switch (code)
+     {
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CONST:
+       return 1;
+ 
+     case LABEL_REF:
+       /* A LABEL_REF is normally invariant, however, if we are unrolling
+ 	 loops, and this label is inside the loop, then it isn't invariant.
+ 	 This is because each unrolled copy of the loop body will have
+ 	 a copy of this label.  If this was invariant, then an insn loading
+ 	 the address of this label into a register might get moved outside
+ 	 the loop, and then each loop body would end up using the same label.
+ 
+ 	 We don't know the loop bounds here though, so just fail for all
+ 	 labels.  */
+       if (flag_unroll_loops)
+ 	return 0;
+       else
+ 	return 1;
+ 
+     case PC:
+     case CC0:
+     case UNSPEC_VOLATILE:
+       return 0;
+ 
+     case REG:
+       /* We used to check RTX_UNCHANGING_P (x) here, but that is invalid
+ 	 since the reg might be set by initialization within the loop.  */
+       if (x == frame_pointer_rtx || x == arg_pointer_rtx)
+ 	return 1;
+       if (loop_has_call
+ 	  && REGNO (x) < FIRST_PSEUDO_REGISTER && call_used_regs[REGNO (x)])
+ 	return 0;
+       if (n_times_set[REGNO (x)] < 0)
+ 	return 2;
+       return n_times_set[REGNO (x)] == 0;
+ 
+     case MEM:
+       /* Read-only items (such as constants in a constant pool) are
+ 	 invariant if their address is.  */
+       if (RTX_UNCHANGING_P (x))
+ 	break;
+ 
+       /* If we filled the table (or had a subroutine call), any location
+ 	 in memory could have been clobbered.  */
+       if (unknown_address_altered
+       /* Don't mess with volatile memory references.  */
+ 	  || MEM_VOLATILE_P (x))
+ 	return 0;
+ 
+       /* See if there is any dependence between a store and this load.  */
+       for (i = loop_store_mems_idx - 1; i >= 0; i--)
+ 	if (rtx_equal_p (XEXP (loop_store_mems[i], 0), XEXP (x, 0)))
+ 	  {
+ 	    return 0;
+ 	  }
+ 
+       /* It's not invalidated by a store in memory
+ 	 but we must still verify the address is invariant.  */
+       break;
+ 
+     case ASM_OPERANDS:
+       /* Don't mess with insns declared volatile.  */
+       if (MEM_VOLATILE_P (x))
+ 	return 0;
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'e')
+ 	{
+ 	  int tem = invariant_p (XEXP (x, i));
+ 	  if (tem == 0)
+ 	    return 0;
+ 	  if (tem == 2)
+ 	    conditional = 1;
+ 	}
+       else if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = 0; j < XVECLEN (x, i); j++)
+ 	    {
+ 	      int tem = invariant_p (XVECEXP (x, i, j));
+ 	      if (tem == 0)
+ 		return 0;
+ 	      if (tem == 2)
+ 		conditional = 1;
+ 	    }
+ 
+ 	}
+     }
+ 
+   return 1 + conditional;
+ }
+ 
+ extern struct reload_slot_info reload_slots[];
+ extern num_reload_stack_slots;
+ extern char call_used_regs[];
+ extern char **insn_name_ptr;
+ 
+ 
+ static struct spill_candidates
+   {
+     /* The stack slot reloaded into this candidate */
+     rtx reload_slot;
+     /* The insn that does the reloading */
+     rtx reload_insn;
+     /* The rtx of the hard register that is reloaded into */
+     rtx hard_reg;
+     /* The mode of the reload slot */
+     enum machine_mode mode;
+     /* Number of times this candidate is set */
+     int num_times_set;
+     /* The pseduo register corresponding to the stack slot */
+     int pseudo_reg;
+     int cur_stack_offset;
+     int reload_indx;
+     /* A linked list of candidates on the same reload stack slot */
+     struct spill_candidates *link_cand;
+     struct spill_candidates *head_cand;
+     unsigned is_head:1;
+     unsigned has_link:1;
+     /* if 1 this candidate is invalid */
+     unsigned disregard:1;
+     /* if 1 the reload stack slot is stored into */
+     unsigned slot_updated_in_loop:1;
+     /* if 1 the pseduo register is live at the loop fall out */
+     unsigned live_at_fall_out:1;
+     /* if 1 the pseduo register is live at a loop jump out */
+     unsigned live_at_jump_out:1;
+     /* if 1 the value in the candidate hard register must be
+        updated into the reload stack slot */
+     unsigned must_update_reload:1;
+     /* if 1 then the candidate hard register was loaded with the
+        reload stack slot before it was used */
+     unsigned first_set_to_reload:1;
+     /* if 1 then the candidate's spill slot has been updated and
+        the candidate is out of synch with it's spill slot intel1a */
+     unsigned slot_updated:1;
+   }
+ 
+ spill_candidate[FIRST_PSEUDO_REGISTER];
+ 
+ static int all_candidates_invalid = 0;
+ static int num_spill_candidates_found = 0;
+ static int *insns_moved_out;
+ static int have_flow_analysis = 0;
+ 
+ /* Find all candidates for spill slot optimization over the loop and
+    move them out. Also try to push spilled invariants back into the
+    loop
+ */
+ static
+ void 
+ move_spills_out (loop_start, loop_end)
+      rtx loop_start;
+      rtx loop_end;
+ {
+   rtx insn;
+   int i, is_loop_exit, regno, indx;
+ 
+   insns_moved_out = (int *) alloca ((max_uid_for_loop + 1) * sizeof (int));
+   bzero (insns_moved_out, (max_uid_for_loop + 1) * sizeof (int));
+   num_reload_stack_slots = 0;
+   num_spill_candidates_found = 0;
+   bzero (spill_candidate, FIRST_PSEUDO_REGISTER * sizeof (spill_candidate[0]));
+   for (i=0; i<FIRST_PSEUDO_REGISTER; i++)
+     {
+       spill_candidate[i].reload_indx = -1;
+     }
+   insn = loop_start;
+   while (insn != PREV_INSN (loop_end))
+     {
+       if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
+ 	  && GET_CODE (PATTERN (insn)) == SET 
+ 	  && GET_CODE (SET_DEST (PATTERN (insn))) == REG 
+ 	  && GET_CODE (SET_SRC (PATTERN (insn))) == MEM 
+ 	  && is_a_stack_slot (SET_SRC (PATTERN (insn)))
+ 	  && (regno = REGNO (SET_DEST (PATTERN (insn)))) < FIRST_PSEUDO_REGISTER
+ 	)
+ 	{
+ 	  indx = -1;
+ 	  if (!is_a_reload_stack_slot (SET_SRC (PATTERN (insn)), &indx, 0, 0))
+ 	    {
+ 	      if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
+ 	        {
+ 	          return;
+ 	        }
+ 	      reload_slots[num_reload_stack_slots].cur_stack_offset = 0;
+ 	      reload_slots[num_reload_stack_slots].reload_stack_mode = -1;
+ 	      reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
+ 	      reload_slots[num_reload_stack_slots].reload_slot_updated = 0;
+ 	      reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg 
+ 		= SPILL_PSEUDO (insn);
+ 	      reload_slots[num_reload_stack_slots].reload_insn = insn; 
+ 	      reload_slots[num_reload_stack_slots++].reload_stack_slot 
+ 		= SET_SRC (PATTERN (insn));
+ 	    }
+ 	  else
+ 	    { /* We have already encountered this reload slot - it
+                  must always be a reload slot of the same pseudo */
+ 	      if (reload_slots[indx].stack_slot_pseudo_reg !=
+ 		  SPILL_PSEUDO (insn))
+ 		{
+ 		  reload_slots[indx].reload_stack_mode == -2;
+ 		}
+ 	    }
+ 	  if (indx == -1) 
+ 	    {
+ 	      indx = num_reload_stack_slots - 1;
+ 	    }
+ 	  if (!(spill_candidate[regno].pseudo_reg == 0 
+ 		|| spill_candidate[regno].pseudo_reg == SPILL_PSEUDO (insn)))
+ 	    { /* Candidate can be for only one spilled pseudo reg */
+               reload_slots[indx].reload_stack_mode = -2;
+               if (spill_candidate[regno].reload_indx != -1)
+                 {
+                   reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
+                 }
+ 	    }
+           else if (spill_candidate[regno].reload_indx != -1
+                    && spill_candidate[regno].reload_indx != indx)
+             { /* Candidates can only be for one reload slot */
+               reload_slots[indx].reload_stack_mode = -2;
+               reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
+             }
+           else 
+ 	    {
+               spill_candidate[regno].pseudo_reg = SPILL_PSEUDO (insn);
+               spill_candidate[regno].reload_indx = indx;
+ 	    }
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+ 
+   all_candidates_invalid = 0;
+   insn = loop_start;
+   while (insn != (loop_end))
+     {
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  mark_spill_candidates (insn, PATTERN (insn));
+ 	  if (all_candidates_invalid)
+ 	    {
+ 	      return;
+ 	    }
+ 	}
+       else if (GET_CODE (insn) == JUMP_INSN)
+ 	{ /* Check if this is a loop exit */
+ 	  is_loop_exit = check_if_jumps_out_of_loop (PATTERN (insn), 1);
+ 	  /* Verify which spill candidates remian valid */
+ 	  if (num_spill_candidates_found)
+ 	    verify_spill_candidates (insn, is_loop_exit);
+ 	  if (all_candidates_invalid)
+ 	    {
+ 	      return;
+ 	    }
+ 	}
+       else if (GET_CODE (insn) == CODE_LABEL && num_spill_candidates_found)
+ 	{
+ 	  /* Verify which spill candidates remian valid */
+ 	  verify_spill_candidates (insn, 0);
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   if (num_spill_candidates_found && !all_candidates_invalid)
+     {
+       int i;
+       rtx rn, prev, link;
+       if (!simplejump_p (PREV_INSN (loop_end)))
+ 	mark_regs_alive_at_exit (NEXT_INSN (loop_end), 1);
+       if (!all_candidates_invalid)
+ 	{
+ 	  move_spill_movables (loop_start, loop_end);
+ 
+ 	  for (rn = loop_start; rn != loop_end; rn = NEXT_INSN (rn))
+ 	    {
+ 	      if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
+ 		   || GET_CODE (rn) == CALL_INSN) && LOG_LINKS (rn))
+ 		{
+ 		  for (prev = 0, link = LOG_LINKS (rn); link;
+ 		       prev = link, link = XEXP (link, 1))
+ 		    {
+ 		      if (insns_moved_out[INSN_UID (XEXP (link, 0))])
+ 			{
+ 			  if (prev)
+ 			    XEXP (prev, 1) = XEXP (link, 1);
+ 			  else
+ 			    LOG_LINKS (rn) = XEXP (link, 1);
+ 			}
+ 		    }
+ 
+ 		}
+ 	    }
+ 	}
+     }
+   if (unknown_address_altered)
+     {
+       return;
+     }
+   for (i = 0; i < num_reload_stack_slots; i++)
+     {
+       if (flag_push_load_into_loop
+ 	  && reload_slots[i].reload_slot_updated == 0 
+ 	  /*&& reload_slots[i].reload_stack_mode != -2 
+ 	  && reload_slots[i].is_loaded_to_reg != -1 
+ 	  && !spill_candidate[reload_slots[i].is_loaded_to_reg].has_link 
+ 	  && spill_candidate[reload_slots[i].is_loaded_to_reg].disregard 
+ 	  && spill_candidate[reload_slots[i].is_loaded_to_reg].live_at_jump_out == 0 
+           && spill_candidate[reload_slots[i].is_loaded_to_reg].live_at_fall_out == 0
+           */
+ 	)
+ 	{
+ 	  /* This is a reload slot that was never updated in loop
+              but could not be lifted only because the register it is
+              loaded into was also set to something else in loop.
+              Lets see if the reload slot was set in the basic block
+              just prior to the loop by some inexpensive operation.
+              (particularly a move from memory into a register and
+              a move of that register onto stack). If so lets
+              replace each load of the reload slot in the loop with
+              a load of the memory and delete the code that loaded
+              and spilled it outside the loop.
+              This corrects the preloading of loop invariants that
+              could not be held in registers over the loop
+            */
+ 	  push_load_into_loop (loop_start, loop_end, i);
+ 	}
+     }
+ }
+ 
+ /* Move the valid spill slot candidates out of the loop and
+    replace the spill slot with the register throughout the loop.
+    Also update the spill slot after the loop if this is necessary */
+ 
+ static
+ void 
+ move_spill_movables (loop_start, loop_end)
+      rtx loop_start, loop_end;
+ {
+   rtx insn;
+   int i, indx, all_are_ok;
+   struct spill_candidates *link_cand;
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       if (spill_candidate[i].disregard == 0 && spill_candidate[i].reload_insn 
+ 	  && spill_candidate[i].num_times_set == n_times_set[i])
+ 	{
+ 	  is_a_reload_stack_slot (spill_candidate[i].reload_slot, &indx, 0, 0);
+           /* Sanity check */
+           if (spill_candidate[i].reload_indx != indx)
+             {
+               abort ();
+             }
+ 	  if (reload_slots[indx].reload_stack_mode == -2)
+ 	    {/* The stack slot was used in some other mode than the
+                  load to the hard reg */
+               spill_candidate[i].disregard = 1;
+ 	      continue;
+ 	    }
+ 	  if (!spill_candidate[i].has_link)
+ 	    {
+ 	      all_are_ok = 1;
+ 	    }
+ 	  else if (spill_candidate[i].is_head)
+ 	    {
+ 	      /* This is a candidate that is the head of a chain of
+                  candidates that all contain the same reload slot.
+                  Go over the linked list to see if all are ok;
+               */
+ 	      all_are_ok = 1;
+ 	      link_cand = spill_candidate[i].link_cand;
+ 	      while (link_cand)
+ 		{
+ 		  all_are_ok = all_are_ok 
+ 		    && link_cand->disregard == 0 
+ 		    && link_cand->num_times_set == 1 
+ 		    && n_times_set[REGNO (link_cand->hard_reg)] == 1 
+ 		    && link_cand->reload_insn;
+ 		  /* So it won't be processed again */
+ 		  link_cand->disregard = 1;
+ 		  link_cand = link_cand->link_cand;
+ 		}
+ 	      if (spill_candidate[i].num_times_set != 1)
+ 		{
+ 		  all_are_ok = 0;
+ 		}
+ 	      if (all_are_ok == 0)
+ 	        {
+ 		  spill_candidate[i].disregard = 1;
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      all_are_ok = 0;
+ 	    }
+ 	  if (all_are_ok)
+ 	    {
+ 	      /* Move the reload insn to just before loop_start */
+ 	      if (loop_dump_stream)
+ 	        {
+ 	          fprintf (loop_dump_stream,
+ 	          "insn %d moved out of loop, stack slot held in reg %d over loop\n",
+ 	          INSN_UID (spill_candidate[i].reload_insn), i);
+ 	          if (spill_candidate[i].is_head)
+ 	            {
+ 		      fprintf (loop_dump_stream, " these regs also shadow the stack slot:");
+ 	              link_cand = spill_candidate[i].link_cand;
+ 	              while (link_cand)
+ 		        {
+ 		          fprintf (loop_dump_stream, " %d", REGNO (link_cand->hard_reg));
+ 		          link_cand = link_cand->link_cand;
+ 		        }
+ 		      fprintf (loop_dump_stream, "\n");
+ 	            }
+ 	        }
+ 	      insn = spill_candidate[i].reload_insn;
+ 	      NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+ 	      PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+ 	      NEXT_INSN (insn) = loop_start;
+ 	      PREV_INSN (insn) = PREV_INSN (loop_start);
+ 	      NEXT_INSN (PREV_INSN (loop_start)) = insn;
+ 	      PREV_INSN (loop_start) = insn;
+ 	      if (INSN_UID (insn) <= max_uid_for_loop)
+ 		{
+ 		  insns_moved_out[INSN_UID (insn)] = 1;
+ 		}
+ 	      if (spill_candidate[i].live_at_fall_out 
+ 		  && spill_candidate[i].slot_updated_in_loop)
+ 		{
+ 		  emit_insn_after (gen_rtx (SET, 0, spill_candidate[i].reload_slot,
+ 					    spill_candidate[i].hard_reg),
+ 				   loop_end);
+ 		}
+ 	    }
+ 	}
+       else
+ 	{
+ 	  spill_candidate[i].disregard = 1;
+ 	  if (spill_candidate[i].has_link && spill_candidate[i].is_head)
+ 	    {  /* invalidate the whole chain */
+ 	      link_cand = spill_candidate[i].link_cand;
+ 	      while (link_cand)
+ 		{
+ 		  link_cand->disregard = 1;
+ 		  link_cand = link_cand->link_cand;
+ 		}
+ 	    }
+ 	}
+     }
+   /* Where ever a reload_slot that is contained is a valid candidate
+      appears in the loop - replace it with that hard_reg */
+   insn = loop_start;
+   while (insn != loop_end)
+     {
+       if (GET_CODE (insn) == INSN)
+ 	{
+           undobuf.num_undo = 0;
+           undobuf.storage = (char *) oballoc (0);
+ 	  replace_spill_slots (insn, PATTERN (insn), &PATTERN (insn));
+ 	  replace_linked_regs (insn, PATTERN (insn));
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+ 
+ }
+ 
+ 
+ /* If pat jumps out of the loop then mark all candidates that
+    correspond to pseudos that are alive at the target of the jump,
+    and return 1
+ */
+ static
+ int 
+ check_if_jumps_out_of_loop (pat, do_mark)
+      rtx pat;
+      int do_mark;
+ {
+   rtx target;
+   int ret_val = 0;
+   int i;
+ 
+   switch (GET_CODE (pat))
+     {
+     case PC:
+     case USE:
+     case CLOBBER:
+     case REG:
+     case MEM:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case RETURN:
+       return (ret_val);
+ 
+     case CONST:
+       /* There could be a label reference in here.  */
+       return (check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark));
+ 
+     case PLUS:
+     case MINUS:
+     case MULT:
+     case LSHIFT:
+       ret_val = check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark);
+       ret_val = ret_val | check_if_jumps_out_of_loop (XEXP (pat, 1), do_mark);
+       return (ret_val);
+ 
+     case SIGN_EXTEND:
+     case ZERO_EXTEND:
+       return (check_if_jumps_out_of_loop (XEXP (pat, 0), do_mark));
+ 
+     case LABEL_REF:
+       if (LABEL_OUTSIDE_LOOP_P (pat))
+ 	{ /* This is a jump to outside of loop */
+ 	  if (do_mark)
+ 	    {
+ 	      target = XEXP (pat, 0);
+ 	      /* Now mark all those pseudo regs not dead at entry
+ 	         to the target block */
+ 	      mark_regs_alive_at_exit (target, 0);
+ 	    }
+ 	  ret_val = 1;
+ 	}
+ 
+       return (ret_val);;
+ 
+     case SET:
+       /* If this is not setting pc, ignore.  */
+       if (SET_DEST (pat) == pc_rtx)
+ 	ret_val = check_if_jumps_out_of_loop (SET_SRC (pat), do_mark);
+       return (ret_val);
+ 
+     case IF_THEN_ELSE:
+       ret_val = check_if_jumps_out_of_loop (XEXP (pat, 1), do_mark);
+       ret_val = ret_val | check_if_jumps_out_of_loop (XEXP (pat, 2), do_mark);
+       return (ret_val);
+ 
+     case PARALLEL:
+     case ADDR_VEC:
+     case ADDR_DIFF_VEC:
+       all_candidates_invalid = 1;
+       return(1);
+ 
+     default:
+       /* Nothing else should occur in a JUMP_INSN.  */
+       abort ();
+     }
+ }
+ 
+ /*
+   block_head, or the first nonnote insn after block_head (if block_head
+   is a note insn), is the head of a block that is the target of a loop
+   exit. if is_loop_fallout is 1 then the loop exit is the normal end of
+   the loop where the loop falls out, otherwise the loop exit was a jump
+   out of the loop. Any candidates whose pseudos are alive at the
+   start of the block are marked (i.e. the stack slot which
+   corresponds to the pseudo must be updated at this loop exit)
+   if the loop exit is NOT the loop fallout then we mark this
+   candidate as not valid
+ */
+ 
+ static
+ void 
+ mark_regs_alive_at_exit (block_head, is_loop_fallout)
+      rtx block_head;
+      int is_loop_fallout;
+ {
+   int i, found, pseudo_regno, block_num, offset, bit;
+   rtx org_block_head = block_head;
+ 
+   i = 0;
+   found = 0;
+   /* Find which block block_head is the head of */
+   if (is_loop_fallout)
+     {
+       while (i < n_basic_blocks && !found)
+         {
+           if (basic_block_head[i] == block_head)
+ 	    {
+ 	      found = 1;
+ 	    }
+           else
+ 	    {
+ 	      i++;
+ 	    }
+         }
+     }
+   if (!found)
+     {
+       while (block_head && GET_CODE (block_head) != CODE_LABEL 
+ 	     && GET_RTX_CLASS (GET_CODE (block_head)) != 'i')
+         {
+           block_head = NEXT_INSN (block_head);
+         }
+       if (block_head == NULL)
+         {
+           if (!is_loop_fallout)
+ 	    { /* block_head must have been a label upon entry and hence
+                  should not be null now */
+ 	      abort ();
+ 	    }
+           return;
+         }
+       i = 0;
+       while (i < n_basic_blocks && !found)
+         {
+           if (basic_block_head[i] == block_head)
+ 	    {
+ 	      found = 1;
+ 	    }
+           else
+ 	    {
+ 	      i++;
+ 	    }
+         }
+     }
+   if (!found)
+     {
+       all_candidates_invalid = 1;
+       return;
+     }
+   block_num = i;
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       if (spill_candidate[i].reload_slot == NULL)
+         { /* A jump out of the loop before it is known
+              if this slot will become a candidate - so
+              just mark it to never become a candidate.
+              Actually we could remember this jump and
+              mark the candidate accordingly in the future
+              but this seems like too much work */
+           spill_candidate[i].disregard = 1;
+         }
+       else
+       if (spill_candidate[i].disregard == 0 
+ 	  && spill_candidate[i].reload_slot)
+ 	{ /* This candidate is still valid */
+ 	  /* Find the pseudo reg that corresponds to this spill slot */
+ 	  pseudo_regno = spill_candidate[i].pseudo_reg;
+ 	  if (pseudo_regno < FIRST_PSEUDO_REGISTER)
+ 	    {
+ 	      abort ();
+ 	    }
+ 	  /* See if this pseudo reg is alive at the beginning of
+              the block that begins at block_head*/
+ 	  offset = pseudo_regno / REGSET_ELT_BITS;
+ 	  bit = 1 << (pseudo_regno % REGSET_ELT_BITS);
+ 	  if (basic_block_live_at_start[block_num][offset] & bit)
+ 	    {
+ 	      if (!is_loop_fallout)
+ 		{ /* Don't want to handle pseudo's that are alive
+                      at targets of jumps out of the loop */
+ 		  spill_candidate[i].disregard = 1;
+ 		  spill_candidate[i].live_at_jump_out = 1;
+ 		}
+ 	      else
+ 		{
+ 		  spill_candidate[i].live_at_fall_out = 1;
+ 		}
+ 	    }
+ 	}
+     }
+ 
+ }
+ 
+ 
+ /* 
+   Verfiy that all spill candidates are still valid
+ */
+ static
+ void 
+ verify_spill_candidates (insn, is_loop_exit)
+      rtx insn;
+      int is_loop_exit;
+ {
+   int i;
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       /* intel1a */
+       spill_candidate[i].slot_updated = 0;
+       if (spill_candidate[i].must_update_reload)
+ 	{
+ 	  spill_candidate[i].disregard = 1;
+ 	}
+       if (GET_CODE (insn) == CODE_LABEL)
+ 	{
+ 	  spill_candidate[i].first_set_to_reload = 0;
+ 	}
+     }
+ }
+ 
+ #ifndef max
+ #define max(a,b) ((a) < (b) ? (b) : (a))
+ #endif
+ 
+ /* Update the spill slot candidate info according to what body does */
+ static
+ void 
+ mark_spill_candidates (insn, body)
+      rtx insn;
+      rtx body;
+ {
+   int regno, i, dummy, indx, cand_num, j, n_regs;
+ 
+ 
+   if (GET_CODE (body) == SET)
+     {
+       if (GET_CODE (SET_DEST (body)) != REG
+           && GET_CODE (SET_DEST (body)) != SUBREG)
+ 	{
+ 	  spill_handle_regs_mentioned (SET_DEST (body));
+ 	}
+       spill_handle_regs_mentioned (SET_SRC (body));
+       if (GET_CODE (SET_DEST (body)) == SUBREG
+            && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
+ 	   && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
+ 
+ 	{
+ 	  regno = REGNO (SUBREG_REG (SET_DEST (body)));
+ 	  n_regs 
+ 	    = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
+ 	           HARD_REGNO_NREGS (regno, 
+ 	                             GET_MODE (SUBREG_REG (SET_DEST (body)))));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 	      spill_candidate[regno + j].disregard = 1;
+ 	      if (spill_candidate[regno + j].reload_indx != -1)
+ 	        {
+ 	          reload_slots[spill_candidate[regno + j].
+ 	              reload_indx].reload_stack_mode = -2;
+ 	        }
+ 	    }
+ 	}
+       else if (GET_CODE (SET_DEST (body)) == REG 
+ 	       && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  /* if body sets a hard register it is of interest */
+ 	  regno = REGNO (SET_DEST (body));
+           n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
+           if (n_regs > 1)
+             {
+               for (j = 0; j < n_regs; j++)
+                 {
+ 	          spill_candidate[regno + j].disregard = 1;
+                 }
+             }
+ 	  spill_candidate[regno].num_times_set++;
+ 	  if (GET_CODE (SET_SRC (body)) == MEM 
+ 	      && is_a_reload_stack_slot (SET_SRC (body), &indx, 0, 0))
+ 	    { /* It sets it to the value in a reload stack slot 
+ 	         The stack slot must always be used in the same mode
+                  as it is used to reload the hard register
+               */
+               /* intel1a */
+ 	      spill_candidate[regno].slot_updated = 0;
+ 	      if (reload_slots[indx].reload_stack_mode == -1)
+ 		{
+ 		  reload_slots[indx].reload_stack_mode 
+ 		     = GET_MODE (SET_SRC (body));
+ 		}
+ 	      else if (reload_slots[indx].reload_stack_mode == -2 
+ 		       || reload_slots[indx].reload_stack_mode 
+ 		             != GET_MODE (SET_SRC (body)))
+ 		{
+ 		  /* reload slot not always used in same mode */
+ 		  reload_slots[indx].reload_stack_mode = -2;
+ 		  spill_candidate[regno].disregard = 1;
+ 		}
+ 	      if (!spill_candidate[regno].disregard)
+ 		{
+ 		  if (spill_candidate[regno].reload_indx != -1
+ 		      && spill_candidate[regno].reload_indx != indx)
+ 		    { /* Same reg loads more than one reload slot -
+                          disregard it */
+ 		      reload_slots[indx].reload_stack_mode = -2;
+ 		      reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
+ 		      spill_candidate[regno].disregard = 1;
+ 		    }
+ 		  else
+ 		    {
+ 			  num_spill_candidates_found++;
+ 			  spill_candidate[regno].first_set_to_reload = 1;
+ 			  spill_candidate[regno].reload_slot 
+ 			    = SET_SRC (body);
+ 			  spill_candidate[regno].hard_reg 
+ 			    = SET_DEST (body);
+ 			  spill_candidate[regno].reload_insn = insn;
+ 			  spill_candidate[regno].mode 
+ 			    = GET_MODE (SET_DEST (body));
+ 			  /* Sanity check */
+ 			  if (spill_candidate[regno].reload_indx != indx
+ 			      && spill_candidate[regno].reload_indx != -1)
+ 			    {
+ 			      abort ();
+ 			    }
+ 			  spill_candidate[regno].reload_indx = indx;
+ 			  if (spill_candidate[regno].slot_updated_in_loop == 0)
+ 			    {
+ 			      spill_candidate[regno].slot_updated_in_loop 
+ 				= reload_slots[indx].reload_slot_updated;
+ 			    }
+ 			  if (spill_candidate[regno].pseudo_reg == 0)
+ 			    {
+ 			      spill_candidate[regno].disregard = 1;
+ 			    }
+ 		    }
+ 		}
+ 	      if (reload_slots[indx].is_loaded_to_reg == -1)
+ 	        {
+ 	          if (reload_slots[indx].reload_stack_mode != -2
+ 	              && spill_candidate[regno].disregard == 0)
+ 	            {
+ 		      reload_slots[indx].is_loaded_to_reg = regno;
+ 		    }
+ 		}
+ 	      else if (regno != reload_slots[indx].is_loaded_to_reg)
+ 		{
+ 		  int loaded_reg;
+ 		  loaded_reg = reload_slots[indx].is_loaded_to_reg;
+ 		  /* Same spill slot already loaded to different hard reg */
+ 		  /* Create a linked list of candidates that load the
+                      same reload slot */
+ 		  if (spill_candidate[reload_slots[indx].is_loaded_to_reg].disregard == 0
+ 		      && GET_MODE (reload_slots[indx].reload_stack_slot) 
+ 		        == GET_MODE (SET_SRC (body)))
+ 		    {
+ 		      if (spill_candidate[regno].has_link == 0)
+ 			{
+ 			  spill_candidate[regno].has_link = 1;
+ 			  spill_candidate[loaded_reg].has_link = 1;
+ 			  spill_candidate[loaded_reg].is_head = 1;
+ 			  spill_candidate[regno].link_cand 
+ 			    = spill_candidate[loaded_reg].link_cand;
+ 			  spill_candidate[loaded_reg].link_cand 
+ 			    = &spill_candidate[regno];
+ 			  spill_candidate[regno].head_cand 
+ 			    = &spill_candidate[loaded_reg];
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      spill_candidate[loaded_reg].disregard = 1;
+ 		      spill_candidate[regno].disregard = 1;
+ 		      reload_slots[indx].reload_stack_mode = -2;
+ 		    }
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      /* reg regno is set to some other value than
+                  a spill stack slot */
+ 	      if (!is_updated_by_const (insn))
+ 		{
+ 		  spill_candidate[regno].disregard = 1;
+ 		  if (spill_candidate[regno].reload_indx != -1)
+ 		    {
+ 		      reload_slots[spill_candidate[regno].reload_indx].reload_stack_mode = -2;
+ 		    }
+ 		}
+ 	      /* It sets it to some other value - signal that by
+                  the end of this block that value must have been
+                  stored into the hard registers reload stack slot
+               */
+ 	      spill_candidate[regno].must_update_reload = 1;
+ 	    }
+ 	}
+       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, 0, 0))
+ 	{ /* This is an update of a reload_stack_slot */
+ 	  if (GET_CODE (SET_DEST (body)) == SUBREG)
+ 	    {
+ 	      reload_slots[indx].reload_stack_mode = -2;
+ 	    }
+ 	  reload_slots[indx].reload_slot_updated = 1;
+ 	  cand_num = reload_slots[indx].is_loaded_to_reg;
+ 	  /* intel1a */
+ 	  if (cand_num != -1)
+ 	    {
+ 	      spill_candidate[cand_num].slot_updated = 1;
+ 	    }
+ 	  if (cand_num == -1)
+ 	    {
+ 	      if (!is_updated_by_const_or_reg (insn))
+ 		{
+ 		  /* An update before a load - must not
+                      become a candidate */
+ 		  reload_slots[indx].reload_stack_mode = -2;
+ 		}
+ 	    }
+ 	  else if (GET_CODE (SET_SRC (body)) == REG 
+ 		   && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER 
+ 		   && GET_MODE (SET_SRC (body)) ==
+ 		   spill_candidate[REGNO (SET_SRC (body))].mode 
+ 		   && rtx_equal_p (
+ 	      XEXP (spill_candidate[REGNO (SET_SRC (body))].reload_slot, 0),
+ 				 XEXP (SET_DEST (body), 0))
+ 	    )
+ 	    {
+ 	      /* It is an update from the appropriate hard reg
+                  and was expected */
+ 	      spill_candidate[cand_num].must_update_reload = 0;
+ 	      spill_candidate[cand_num].slot_updated_in_loop = 1;
+ 	    }
+ 	  else if (spill_candidate[cand_num].must_update_reload != 0)
+ 	    { /* It was expected to be updated by the hard
+                  register but it wasn't - the hard register
+                  that has this as a reload stack slot is no
+                  longer to be considered a candidate */
+ 	      spill_candidate[cand_num].disregard = 1;
+ 	      if (spill_candidate[cand_num].reload_indx != -1)
+ 	        {
+ 		  reload_slots[spill_candidate[cand_num].reload_indx].reload_stack_mode = -2;
+ 		}
+ 	    }
+ 	  else if (!is_updated_by_const_or_reg (insn))
+ 	    {
+ 	      spill_candidate[cand_num].disregard = 1;
+ 	      if (spill_candidate[cand_num].reload_indx != -1)
+ 	        {
+ 		  reload_slots[spill_candidate[cand_num].reload_indx].reload_stack_mode = -2;
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      spill_candidate[cand_num].slot_updated_in_loop = 1;
+ 	    }
+ 	}
+     }
+   else if (GET_CODE (body) == CLOBBER)
+     {
+       if (GET_CODE (SET_DEST (body)) == REG 
+ 	  && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  regno = REGNO (SET_DEST (body));
+ 	  n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 	      spill_candidate[regno + j].disregard = 1;
+ 	      if (spill_candidate[regno + j].reload_indx != -1)
+ 	        {
+ 	          reload_slots[spill_candidate[regno + j].
+ 	              reload_indx].reload_stack_mode = -2;
+ 	        }
+ 	    }
+ 	}
+       else if (GET_CODE (SET_DEST (body)) == SUBREG
+                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
+ 	       && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
+ 
+ 	{
+ 	  regno = REGNO (SUBREG_REG (SET_DEST (body)));
+ 	  n_regs 
+ 	    = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
+ 	           HARD_REGNO_NREGS (regno, 
+ 	                             GET_MODE (SUBREG_REG (SET_DEST (body)))));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 	      spill_candidate[regno + j].disregard = 1;
+ 	      if (spill_candidate[regno + j].reload_indx != -1)
+ 	        {
+ 	          reload_slots[spill_candidate[regno + j].
+ 	              reload_indx].reload_stack_mode = -2;
+ 	        }
+ 	    }
+ 	}
+     }
+   else if (GET_CODE (body) == PARALLEL)
+     {
+       for (i = 0; i < XVECLEN (body, 0); i++)
+ 	mark_spill_candidates (insn, XVECEXP (body, 0, i));
+     }
+   else
+     {
+       all_candidates_invalid = 1;
+     }
+ }
+ 
+ 
+ /*
+   Called to mark cnadidates that are invalid at this point */
+ static
+ void 
+ spill_handle_regs_mentioned (pat)
+      rtx pat;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+   int indx;
+ 
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+     case REG:
+       if (REGNO (pat) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  /* intel1a */
+ 	  if (spill_candidate[REGNO (pat)].slot_updated)
+ 	    {
+ 	      spill_candidate[REGNO (pat)].disregard = 1;
+ 	      for (i=0; i < num_reload_stack_slots; i++)
+ 	        {
+ 	          if (reload_slots[i].is_loaded_to_reg == REGNO (pat))
+ 	            {
+ 	              reload_slots[i].reload_stack_mode = -2;
+ 	            }
+ 	        }
+ 	    }
+ 	  if (!spill_candidate[REGNO (pat)].first_set_to_reload)
+ 	    {
+ 	      spill_candidate[REGNO (pat)].disregard = 1;
+ 	      for (i=0; i < num_reload_stack_slots; i++)
+ 	        {
+ 	          if (reload_slots[i].is_loaded_to_reg == REGNO (pat))
+ 	            {
+ 	              reload_slots[i].reload_stack_mode = -2;
+ 	            }
+ 	        }
+ 	    }
+ 	}
+       return;
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return;
+ 
+ 
+     }
+   /* The reload stack slot must always be accessed in the same mode */
+   if ((GET_CODE (pat) == MEM || GET_CODE (pat) == SUBREG)
+       && is_a_reload_stack_slot (pat, &indx, 0, 0))
+     {
+       if (GET_CODE (pat) == SUBREG)
+         {
+ 	  /* Signal invalid */
+ 	  reload_slots[indx].reload_stack_mode = -2;
+         }
+       else if (reload_slots[indx].reload_stack_mode == -1)
+ 	{
+ 	  reload_slots[indx].reload_stack_mode = GET_MODE (pat);
+ 	}
+       else if (reload_slots[indx].reload_stack_mode != GET_MODE (pat))
+ 	{
+ 	  /* Signal invalid */
+ 	  reload_slots[indx].reload_stack_mode = -2;
+ 	}
+     }
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    spill_handle_regs_mentioned (XVECEXP (pat, i, j));
+ 	}
+       else if (fmt[i] == 'e')
+ 	spill_handle_regs_mentioned (XEXP (pat, i));
+     }
+ }
+ 
+ 
+ /*
+   Return 1 if insn updates a value by a constant value */
+ static
+ int 
+ is_updated_by_const (insn)
+      rtx insn;
+ {
+   if (GET_CODE (PATTERN (insn)) != SET)
+     {
+       return (0);
+     }
+   if (GET_RTX_LENGTH (GET_CODE (SET_SRC (PATTERN (insn)))) != 2)
+     {
+       return (0);
+     }
+   if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0),
+ 		    SET_DEST (PATTERN (insn))))
+     {
+       return (0);
+     }
+   if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != CONST_INT)
+     {
+       return (0);
+     }
+   return (1);
+ }
+ 
+ 
+ /*
+   Return 1 if insn updates a value by a constant value or register */
+ static
+ int 
+ is_updated_by_const_or_reg (insn)
+      rtx insn;
+ {
+   if (GET_CODE (PATTERN (insn)) != SET)
+     {
+       return (0);
+     }
+   if (GET_RTX_LENGTH (GET_CODE (SET_SRC (PATTERN (insn)))) != 2)
+     {
+       return (0);
+     }
+   if (!rtx_equal_p (XEXP (SET_SRC (PATTERN (insn)), 0),
+ 		    SET_DEST (PATTERN (insn))))
+     {
+       return (0);
+     }
+   if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != CONST_INT
+       && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 1)) != REG)
+     {
+       return (0);
+     }
+   return (1);
+ }
+ 
+ 
+ /* Go over the whole function and do
+ 
+    spill_slotA <- regY                     spill_slotA <- regY
+         .  sequence of code not                 .  sequence of code not
+         .  affecting regY or       =>           .  affecting regY or
+         .  spill_slotA                          .  spill_slotA
+    regX <- spill_slotA                     regX <- regY
+ */
+ void 
+ peep_spills (f, dumpfile)
+      rtx f;
+      FILE * dumpfile;
+ {
+   rtx insn, next, note;
+   int i, indx, insn_code_number, success;
+ 
+   undobuf.num_undo = 0;
+   num_reload_stack_slots = 0;
+   cur_stack_offset = 0;
+   bzero (spill_candidate, FIRST_PSEUDO_REGISTER * sizeof (spill_candidate[0]));
+   loop_dump_stream = dumpfile;
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "\n\nDoing peep spills\n\n");
+     }
+   insn = f;
+   while (insn)
+     {
+       if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
+ 	  && GET_CODE (SET_SRC (PATTERN (insn))) == MEM 
+ 	  && is_a_stack_slot (SET_SRC (PATTERN (insn)))
+ 	  && !is_a_reload_stack_slot (SET_SRC (PATTERN (insn)), &indx,
+ 	                              cur_stack_offset, 0) )
+ 	{	
+ 	  if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
+ 	    {
+ 	      return;
+ 	    }
+ 	  if (loop_dump_stream)
+ 	    {
+ 	      fprintf (loop_dump_stream, "reload slot at insn %d offset %d %d %d\n",
+ 	      INSN_UID (insn), cur_stack_offset,
+ 	      RTX_IS_SPILL_P (SET_SRC (PATTERN (insn))),
+ 	      RTX_IS_SPILL_P (XEXP (SET_SRC (PATTERN (insn)), 0)));
+ 	    }
+ 	  reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
+ 	  reload_slots[num_reload_stack_slots].last_store = NULL;
+ 	  reload_slots[num_reload_stack_slots].cur_stack_offset 
+ 	    = cur_stack_offset;
+ 	  reload_slots[num_reload_stack_slots].reload_stack_slot 
+ 	    = SET_SRC (PATTERN (insn));
+ 	  reload_slots[num_reload_stack_slots++].reload_insn = insn; 
+ 	}
+       else if (GET_CODE (insn) == INSN && RTX_IS_SPILL_P (insn) 
+ 	  && GET_CODE (SET_DEST (PATTERN (insn))) == MEM 
+ 	  && is_a_stack_slot (SET_DEST (PATTERN (insn)))
+ 	  && !is_a_reload_stack_slot (SET_DEST (PATTERN (insn)), &indx,
+ 	                              cur_stack_offset, 0) )
+ 	{	
+ 	  if (num_reload_stack_slots >= MAX_RELOAD_STACK_SLOTS)
+ 	    {
+ 	      return;
+ 	    }
+ 	  if (loop_dump_stream)
+ 	    {
+ 	      fprintf (loop_dump_stream, "reload slot at insn %d offset %d\n",
+ 	      INSN_UID (insn), cur_stack_offset);
+ 	    }
+ 	  reload_slots[num_reload_stack_slots].is_loaded_to_reg = -1;
+ 	  reload_slots[num_reload_stack_slots].last_store = NULL;
+ 	  reload_slots[num_reload_stack_slots].cur_stack_offset 
+ 	    = cur_stack_offset;
+ 	  reload_slots[num_reload_stack_slots].reload_stack_slot 
+ 	    = SET_DEST (PATTERN (insn));
+ 	  reload_slots[num_reload_stack_slots++].reload_insn = insn; 
+ 	}
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  if (GET_CODE (PATTERN (insn)) == SET)
+ 	    update_stack_offset (PATTERN (insn), &cur_stack_offset);
+ 	  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	    {
+ 	      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ 		update_stack_offset (XVECEXP (PATTERN (insn), 0, i), 
+ 		                     &cur_stack_offset);
+ 	    }
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   cur_stack_offset = 0;
+   insn = f;
+   while (insn)
+     {
+       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ 	{
+ 	  spill_peep_insn (insn, PATTERN (insn));
+ 	  if (have_flow_analysis 
+ 		&& GET_CODE (PATTERN (insn)) == SET
+ 		&& GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ 		&& GET_CODE (SET_SRC (PATTERN (insn))) == REG
+ 		&& (next = next_nonnote_insn (insn))
+ 		&& GET_CODE (next) == INSN
+ 		&& GET_CODE (next) == INSN
+ 		&& (note = find_regno_note (next, 
+ 		                    REG_DEAD, 
+ 		                    REGNO (SET_DEST (PATTERN (insn)))))
+ 		&& rtx_equal_p (XEXP (note, 0), SET_DEST (PATTERN (insn)))
+ 	     )
+             { /* we have reg1 <- reg2 and reg1 dead in next insn
+               replace reg1 with reg2 in next insn and delete this
+               insn */
+               init_undo_buf ();
+               subst_in_insn (next,
+                              PATTERN (next),
+                              SET_DEST (PATTERN (insn)),
+                              SET_SRC (PATTERN (insn)),
+                              0,
+                              0);
+               if (reg_overlap_mentioned_p (XEXP (note, 0), PATTERN (next))
+                   || (insn_code_number = recog (PATTERN (next), next, 0)) < 0)
+                 {
+                   loop_undo_all ();
+                   success = 0;
+                 }
+               else
+                 {
+                   success = 1;
+ #ifdef REGISTER_CONSTRAINTS
+                   INSN_CODE (next) = insn_code_number;
+                   insn_extract (next);
+                   if (!constrain_operands (insn_code_number, 1))
+                     {
+                       loop_undo_all ();
+                       INSN_CODE (next) 
+                         = recog (PATTERN (next), 
+                                  next, 0);
+                       success = 0;
+                     }
+ #endif
+                   if (success)
+                     {
+                       if (loop_dump_stream)
+                         {
+                           fprintf (loop_dump_stream,
+                           "replace reg %d with reg %d in insn %d, delete insn %d\n",
+                           REGNO (SET_DEST (PATTERN (insn))),
+                           REGNO (SET_SRC (PATTERN (insn))),
+                           INSN_UID (next), INSN_UID (insn));
+                         }
+ 		      PUT_CODE (insn, NOTE);
+ 		      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 		      NOTE_SOURCE_FILE (insn) = 0;
+ 		      remove_note (next, note);
+                     }
+                 }
+             }
+         }
+       else if (GET_CODE (insn) == CODE_LABEL)
+ 	{
+ 	  peep_init_info ();
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   have_flow_analysis = 0;
+ }
+ 
+ static
+ void 
+ peep_init_info ()
+ {
+   int i;
+   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+     {
+       spill_candidate[i].reload_slot = 0;
+       spill_candidate[i].disregard = 0;
+     }
+   for (i=0; i < num_reload_stack_slots; i++)
+     {
+       reload_slots[i].is_loaded_to_reg = -1;
+       reload_slots[i].last_store = NULL;
+     }
+ }
+ 
+ 
+ /*
+   In body of insn replace any reload stack slots with registers that
+   have the same value
+ */
+ static
+ void 
+ spill_peep_insn (insn, body)
+      rtx insn;
+      rtx body;
+ {
+   enum rtx_code code;
+   int i, j, indx, regno, cand_num, insn_code_number, cur_code_number, success,
+       n_regs;
+ 
+   undobuf.num_undo = 0;
+   code = GET_CODE (body);
+ 
+   if (code == SET)
+     {
+     
+       if (/*cur_stack_offset == 0*/ 1)
+ 	{
+ 	  if (GET_CODE (SET_SRC (body)) == MEM 
+ 	      && is_a_reload_stack_slot (SET_SRC (body), &indx, cur_stack_offset, 0))
+ 	    {
+ 	      cand_num = reload_slots[indx].is_loaded_to_reg;
+ 	      if (cand_num != -1 && spill_candidate[cand_num].disregard == 0 
+ 		  && spill_candidate[cand_num].reload_slot 
+ 		  && GET_MODE (spill_candidate[cand_num].reload_slot)
+ 		       == GET_MODE (SET_SRC (body))
+ 		  && are_same_reload_slots (spill_candidate[cand_num].reload_slot,
+ 		               spill_candidate[cand_num].cur_stack_offset,
+ 			       SET_SRC (body), cur_stack_offset))
+ 		{
+ 		  SET_SRC (body) = spill_candidate[cand_num].hard_reg;
+ 		  if ((insn_code_number = recog (PATTERN (insn), insn, 0)) < 0)
+ 		    {
+ 		      SET_SRC (body) = spill_candidate[cand_num].reload_slot;
+ 		    }
+ 		  else
+ 		    {
+ 		      success = 1;
+ #ifdef REGISTER_CONSTRAINTS
+ 		      INSN_CODE (insn) = insn_code_number;
+ 		      insn_extract (insn);
+ 		      if (!constrain_operands (insn_code_number, 1))
+ 			{
+ 			  SET_SRC (body) 
+ 			    = spill_candidate[cand_num].reload_slot;
+ 			  INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
+ 			  success = 0;
+ 			}
+ #endif
+ 		      if (success && loop_dump_stream)
+ 			{
+ 			  fprintf (loop_dump_stream,
+ 			     " replacing stack slot (src) with reg%d in insn %d\n",
+ 				   REGNO (spill_candidate[cand_num].hard_reg), INSN_UID (insn));
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	  else
+ 	    {
+               undobuf.storage = (char *) oballoc (0);
+ 	      replace_spill_slots (insn, SET_SRC (body), &SET_SRC (body));
+ 	      if (undobuf.num_undo)
+ 	        {
+ 		  if ((insn_code_number = recog (PATTERN (insn), insn, 0)) < 0)
+ 		    {
+ 		      loop_undo_all ();
+ 		      if (loop_dump_stream)
+ 			{
+ 			   fprintf (loop_dump_stream, "  replacment did not succeed %d\n", INSN_UID (insn));
+ 			}
+ 		    }
+ #ifdef REGISTER_CONSTRAINTS
+ 		  else
+ 		    {
+ 		      INSN_CODE (insn) = insn_code_number;
+ 		      insn_extract (insn);
+ 		      if (!constrain_operands (insn_code_number, 1))
+ 			{
+ 			  loop_undo_all ();
+ 		          INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
+ 			  if (loop_dump_stream)
+ 			    {
+ 			      fprintf (loop_dump_stream, "  replacment did not succeed %d\n", INSN_UID (insn));
+ 			    }
+ 			}
+ 		    }
+ #endif
+                   undobuf.num_undo = 0;
+                 }
+ 	    }
+ 	}
+       if (GET_CODE (SET_DEST (body)) == REG
+ 	  && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  regno = REGNO (SET_DEST (body));
+ 	  if (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))) > 1)
+ 	    {
+ 	      regno = REGNO (SET_DEST (body));
+ 	      n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
+ 	      for (j = 0; j < n_regs; j++)
+ 	        {
+ 		      spill_candidate[regno + j].disregard = 1;
+ 	              spill_candidate[regno + j].reload_slot = NULL;
+ 	              for (i=0; i < num_reload_stack_slots; i++)
+ 	                {
+ 	                  if (reload_slots[i].is_loaded_to_reg == regno + i)
+ 	                    {
+ 	                      reload_slots[i].is_loaded_to_reg = -1;
+ 	                    }
+ 	                }
+ 	        }
+ 	    }
+ 	  if (GET_CODE (SET_SRC (body)) == MEM 
+ 	      && is_a_reload_stack_slot (SET_SRC (body), &indx, cur_stack_offset, 0) 
+ 	      && HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))) == 1)
+ 	    { /* It sets it to the value in a reload stack slot */
+ 	      spill_candidate[regno].reload_slot = SET_SRC (body);
+ 	      spill_candidate[regno].hard_reg = SET_DEST (body);
+ 	      spill_candidate[regno].disregard = 0;
+ 	      spill_candidate[regno].reload_insn = insn;
+ 	      spill_candidate[regno].cur_stack_offset = cur_stack_offset;
+               reload_slots[indx].last_store = NULL;
+ 	      reload_slots[indx].is_loaded_to_reg = regno;
+ 	    }
+ 	  else
+ 	    {
+ 	      spill_candidate[regno].disregard = 1;
+ 	      spill_candidate[regno].reload_slot = NULL;
+ 	      for (i=0; i < num_reload_stack_slots; i++)
+ 	        {
+ 	          if (reload_slots[i].is_loaded_to_reg == regno)
+ 	            {
+ 	              reload_slots[i].is_loaded_to_reg = -1;
+ 	            }
+ 	        }
+ 	    }
+ 	}
+       else if (GET_CODE (SET_DEST (body)) == SUBREG
+                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
+ 	       && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
+ 	{ /* Simple handling of subregs - invalidate the subreg being set */
+ 	  regno = REGNO (SUBREG_REG (SET_DEST (body)));
+ 	  n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 		  spill_candidate[regno + j].disregard = 1;
+ 	          spill_candidate[regno + j].reload_slot = NULL;
+ 	          for (i=0; i < num_reload_stack_slots; i++)
+ 	            {
+ 	              if (reload_slots[i].is_loaded_to_reg == regno + i)
+ 	                {
+ 	                  reload_slots[i].is_loaded_to_reg = -1;
+ 	                }
+ 	            }
+ 	    }
+ 	}
+       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, cur_stack_offset, 0))
+ 	{ /* This is an update of a reload_stack_slot */
+               /* Check if last write into this reload slot can be deleted */
+               if (reload_slots[indx].last_store
+                   && GET_CODE (SET_DEST (body)) != SUBREG
+                   /* && GET_CODE (SET_SRC (body)) == REG */
+ 		  && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
+  	          && GET_MODE (SET_DEST ( PATTERN (reload_slots[indx].last_store)))
+ 	              == GET_MODE (SET_DEST (body))
+                   && spill_slot_unused_between (
+                       SET_DEST ( PATTERN (reload_slots[indx].last_store)),
+                       reload_slots[indx].last_store, insn))
+                 {
+                   if (loop_dump_stream)
+                     {
+                       fprintf (loop_dump_stream, "delete redundant spill store at %d becuase of re-store at %d\n",
+                                INSN_UID (reload_slots[indx].last_store),
+                                INSN_UID (insn));
+                     }
+ 		  PUT_CODE (reload_slots[indx].last_store, NOTE);
+ 		  NOTE_LINE_NUMBER (reload_slots[indx].last_store) = NOTE_INSN_DELETED;
+ 		  NOTE_SOURCE_FILE (reload_slots[indx].last_store) = 0;
+ 		  reload_slots[indx].is_loaded_to_reg = -1;
+ 		  reload_slots[indx].last_store = NULL;
+                  }
+ 	      if (GET_CODE (SET_SRC (body)) == REG 
+                   && GET_CODE (SET_DEST (body)) != SUBREG
+ 	          &&HARD_REGNO_NREGS(REGNO(SET_SRC(body)),
+ 			  		GET_MODE(SET_DEST(body))) == 1
+ 		  && REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER)
+ 		{
+ 		  regno = REGNO (SET_SRC (body));
+ 		  spill_candidate[regno].reload_slot = SET_DEST (body);
+ 		  spill_candidate[regno].hard_reg = SET_SRC (body);
+ 		  spill_candidate[regno].disregard = 0;
+ 		  spill_candidate[regno].reload_insn = insn;
+         	  spill_candidate[regno].cur_stack_offset = cur_stack_offset;
+         	  reload_slots[indx].last_store = insn;
+ 		  reload_slots[indx].is_loaded_to_reg = regno;
+ 		}
+ 	      else
+ 	        {
+                   regno = reload_slots[indx].is_loaded_to_reg;
+                   if (regno != -1)
+                     { /* This candidate is now invalid */
+ 		       spill_candidate[regno].disregard = 1;
+ 		       spill_candidate[regno].reload_slot = NULL;
+                     }
+ 		  reload_slots[indx].is_loaded_to_reg = -1;
+ 		  reload_slots[indx].last_store = NULL;
+ 	        }
+ 	}
+       update_stack_offset (body, &cur_stack_offset);
+     }
+   else if (code == CLOBBER)
+     {
+       if (GET_CODE (SET_DEST (body)) == REG 
+ 	  && REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  regno = REGNO (SET_DEST (body));
+ 	  n_regs = HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body)));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 	      spill_candidate[regno + j].disregard = 1;
+ 	      for (i=0; i < num_reload_stack_slots; i++)
+ 	        {
+ 	          if (reload_slots[i].is_loaded_to_reg == (regno + j))
+ 	            {
+ 	              reload_slots[i].is_loaded_to_reg = -1;
+ 	            }
+ 	        }
+ 	    }
+ 	}
+       else if (GET_CODE (SET_DEST (body)) == SUBREG
+                && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG 
+ 	       && REGNO (SUBREG_REG (SET_DEST (body))) < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  regno = REGNO (SUBREG_REG (SET_DEST (body)));
+ 	  n_regs 
+ 	    = max (HARD_REGNO_NREGS (regno, GET_MODE (SET_DEST (body))),
+ 	           HARD_REGNO_NREGS (regno, 
+ 	                             GET_MODE (SUBREG_REG (SET_DEST (body)))));
+ 	  for (j = 0; j < n_regs; j++)
+ 	    {
+ 	      spill_candidate[regno + j].disregard = 1;
+ 	      for (i=0; i < num_reload_stack_slots; i++)
+ 	        {
+ 	          if (reload_slots[i].is_loaded_to_reg == (regno + j))
+ 	            {
+ 	              reload_slots[i].is_loaded_to_reg = -1;
+ 	            }
+ 	        }
+ 	    }
+ 	}
+       else if (is_a_reload_stack_slot (SET_DEST (body), &indx, cur_stack_offset, 0))
+         {
+           regno = reload_slots[indx].is_loaded_to_reg;
+           if (regno != -1)
+             { /* This candidate is now invalid */
+ 		spill_candidate[regno].disregard = 1;
+ 		spill_candidate[regno].reload_slot = NULL;
+ 	    }
+           reload_slots[indx].is_loaded_to_reg = -1;
+ 	  reload_slots[indx].last_store = NULL;
+         }
+     }
+   if (code == PARALLEL)
+     {
+       for (i = 0; i < XVECLEN (body, 0); i++)
+ 	spill_peep_insn (insn, XVECEXP (body, 0, i));
+     }
+   if (GET_CODE (insn) == CALL_INSN)
+     { /* All call clobbered registers are no longer valid */
+       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	{
+ 	  if (call_used_regs[i])
+ 	    {
+ 	      spill_candidate[i].disregard = 1;
+ 	      for (j=0; j < num_reload_stack_slots; j++)
+ 	        {
+ 	          if (reload_slots[j].is_loaded_to_reg == i)
+ 	            {
+ 	              reload_slots[j].is_loaded_to_reg = -1;
+ 	            }
+ 	        }
+ 	    }
+ 	}
+     }
+ }
+ 
+ /*
+   Return 1 iff we are sure that the spill_slot  (or any subpart of it)
+   is not refernced between start and end.  Also there must be no 
+   CALL JUMP or LABELs in between them
+ */
+ static
+ int
+ spill_slot_unused_between (spill_slot, start, end)
+   rtx spill_slot, start, end;
+ {
+   rtx tinsn;
+   int mcur_stack_offset = 0;
+ 
+   for (tinsn = next_nonnote_insn (start);
+        tinsn && tinsn != end;
+        tinsn = next_nonnote_insn (tinsn))
+     {
+       if (GET_CODE (tinsn) == CALL_INSN || GET_CODE (tinsn) == JUMP_INSN 
+           || GET_CODE (tinsn) == CODE_LABEL)
+         {
+           return (0);
+         }
+       if (spill_slot_mentioned(spill_slot, PATTERN (tinsn), mcur_stack_offset))
+         {
+           return (0);
+         }
+       update_stack_offset (PATTERN (tinsn), &mcur_stack_offset);
+     }
+   return (1);
+ }
+ 
+ /*
+   Return 1 if spill_slot or any part of it is mentioned in pat.
+   relative_stack_offset is the offset of the stack pointer relative
+   to the point at which spill_slot was stored into.  
+ */
+ 
+ static int
+ spill_slot_mentioned (spill_slot, pat, relative_stack_offset)
+      rtx pat, spill_slot;
+      int relative_stack_offset;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+ 
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case REG:
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return (0);
+ 
+     case MEM:
+       if (is_a_stack_slot (pat)
+           && are_same_reload_slots (spill_slot, 0, pat, relative_stack_offset))
+         {
+           return (1);
+         }
+       return (0);
+ 
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    if (spill_slot_mentioned (spill_slot, XVECEXP (pat, i, j),
+ 	                              relative_stack_offset))
+ 	      {
+ 	        return (1);
+ 	      }
+ 	}
+       else if (fmt[i] == 'e')
+ 	if (spill_slot_mentioned (spill_slot, XEXP (pat, i),
+ 	                              relative_stack_offset))
+ 	  {
+ 	    return (1);
+ 	  }
+     }
+   return (0);
+ }
+ 
+ 
+ /*
+   Keep track of the depth of the stack
+ */
+ /* static */
+ void 
+ update_stack_offset (pat, addr_stack_offset)
+      rtx pat;
+      int *addr_stack_offset;
+ {
+   int i;
+   if (GET_CODE (pat) != SET)
+     {
+       return;
+     }
+   if (GET_CODE (SET_DEST (pat)) == REG
+       && XINT (SET_DEST (pat), 0) == STACK_POINTER_REGNUM
+       && GET_CODE (SET_SRC (pat)) == PLUS
+       && GET_CODE (XEXP (SET_SRC (pat), 0)) == REG
+       && XINT (XEXP (SET_SRC (pat), 0), 0) == STACK_POINTER_REGNUM)
+     {
+       *addr_stack_offset -= XINT (XEXP (SET_SRC (pat), 1), 0);
+     }
+   else if (GET_CODE (SET_DEST (pat)) == MEM 
+ 	   && GET_CODE (XEXP (SET_DEST (pat), 0)) == PRE_DEC
+ 	   && XEXP (XEXP (SET_DEST (pat), 0), 0) == stack_pointer_rtx)
+     {
+       spill_candidate[STACK_POINTER_REGNUM].disregard = 1;
+       for (i=0; i < num_reload_stack_slots; i++)
+ 	{
+ 	  if (reload_slots[i].is_loaded_to_reg == STACK_POINTER_REGNUM)
+ 	    {
+ 	      reload_slots[i].is_loaded_to_reg = -1;
+ 	    }
+ 	}
+       *addr_stack_offset += GET_MODE_SIZE (GET_MODE (SET_DEST (pat)));
+     }
+   else if (GET_CODE (SET_DEST (pat)) == MEM 
+ 	   && GET_CODE (XEXP (SET_DEST (pat), 0)) == PRE_INC
+ 	   && XEXP (XEXP (SET_DEST (pat), 0), 0) == stack_pointer_rtx)
+     {
+       spill_candidate[STACK_POINTER_REGNUM].disregard = 1;
+       for (i=0; i < num_reload_stack_slots; i++)
+ 	{
+ 	  if (reload_slots[i].is_loaded_to_reg == STACK_POINTER_REGNUM)
+ 	    {
+ 	      reload_slots[i].is_loaded_to_reg = -1;
+ 	    }
+ 	}
+       *addr_stack_offset -= GET_MODE_SIZE (GET_MODE (SET_DEST (pat)));
+     }
+ }
+ 
+ 
+ /*
+   Replace stack spill slots in pat of insn with the appropriate spill
+   candidate
+ */
+ static
+ void
+ replace_spill_slots (insn, pat, where)
+      rtx insn;
+      rtx pat;
+      rtx *where;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+   int cand_num, indx;
+   rtx note;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+     case REG:
+       return;
+ 
+     default:
+       break;
+     }
+   if (GET_CODE (pat) == MEM && is_a_reload_stack_slot (pat, &indx, cur_stack_offset, 0))
+     {
+       cand_num = reload_slots[indx].is_loaded_to_reg;
+       if (cand_num != -1 && spill_candidate[cand_num].disregard == 0 
+ 	  && spill_candidate[cand_num].reload_slot 
+ 	  && GET_MODE (spill_candidate[cand_num].reload_slot)
+ 	       == GET_MODE (pat)
+ 	  && are_same_reload_slots (spill_candidate[cand_num].reload_slot,
+ 	                            spill_candidate[cand_num].cur_stack_offset,
+ 	                            pat, cur_stack_offset))
+ 	{
+ 	  note = find_reg_note (spill_candidate[cand_num].reload_insn,
+ 				REG_DEAD,
+ 				spill_candidate[cand_num].hard_reg);
+ 	  if (note)
+ 	    {
+ 	      remove_note (spill_candidate[cand_num].reload_insn, note);
+ 	    }
+ 	  if (loop_dump_stream)
+ 	    {
+ 	      fprintf (loop_dump_stream, " replacing stack slot with reg%d in insn %d\n",
+ 	       REGNO (spill_candidate[cand_num].hard_reg), INSN_UID (insn));
+ 	    }
+ 	  LOOP_SUBST (where, spill_candidate[cand_num].hard_reg);
+ 	}
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       replace_spill_slots (insn, XEXP (pat, i), &XEXP (pat, i));
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  replace_spill_slots (insn, XVECEXP (pat, i, j), &XVECEXP (pat, i, j));
+       }
+ }
+ 
+ /*
+   Replace any hard registers in pat of insn, that are on a linked
+   list of spill candidates, with the head candidate of the list
+ */
+ static
+ rtx 
+ replace_linked_regs (insn, pat)
+      rtx insn;
+      rtx pat;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+   int cand_num, indx;
+   rtx note;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return pat;
+ 
+     case REG:
+       if (spill_candidate[REGNO (pat)].head_cand 
+ 	  && (spill_candidate[REGNO (pat)].head_cand)->disregard == 0)
+ 	{
+ 	  if (loop_dump_stream)
+ 	    {
+ 	      fprintf (loop_dump_stream, " replacing reg%d with reg%d in insn %d\n",
+ 		       REGNO (pat),
+ 		 REGNO ((spill_candidate[REGNO (pat)].head_cand)->hard_reg),
+ 		       INSN_UID (insn));
+ 	    }
+ 	  return ((spill_candidate[REGNO (pat)].head_cand)->hard_reg);
+ 	}
+       else
+ 	return pat;
+ 
+     default:
+       break;
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       XEXP (pat, i) = replace_linked_regs (insn, XEXP (pat, i));
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  XVECEXP (pat, i, j) 
+ 	    = replace_linked_regs (insn, XVECEXP (pat, i, j));
+       }
+   return pat;
+ }
+ 
+ 
+ /*
+   Mark all registers mentioned in insns between loop_start and loop_end
+   and that are also mentioned outside of the loop
+ */
+ static void
+ mark_regs_live_outside (loop_start, loop_end)
+      rtx loop_start;
+      rtx loop_end;
+ {
+   rtx insn;
+   int in_loop = 0;
+ 
+   insn = get_insns ();
+   while (insn)
+     {
+       if (insn == loop_start)
+ 	{
+ 	  in_loop = 1;
+ 	}
+       else if (insn == loop_end)
+ 	{
+ 	  in_loop = 0;
+ 	}
+       else if (in_loop == 0 
+ 	       && (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN 
+ 		|| GET_CODE (insn) == JUMP_INSN))
+ 	{
+ 	  mark_regs_mentioned (PATTERN (insn), insn);
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+ }
+ 
+ 
+ /*
+   Each register mentioned in pat, except for the destination register of
+   the insn, is marked as reg_live_outside_loop
+ */
+ static void
+ mark_regs_mentioned (pat, insn)
+      rtx pat, insn;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+ 
+   if (GET_CODE (pat) == SET
+       && GET_CODE (SET_DEST (pat)) == REG && is_a_param_slot (SET_SRC (pat)))
+     {
+       return;
+     }
+     
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+     case REG:
+       if (REGNO (pat) < max_reg_before_loop)
+ 	{
+ 	  reg_live_outside_loop[REGNO (pat)] = 1;
+ 	}
+       return;
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return;
+ 
+ 
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    mark_regs_mentioned (XVECEXP (pat, i, j), insn);
+ 	}
+       else if (fmt[i] == 'e')
+ 	mark_regs_mentioned (XEXP (pat, i), insn);
+     }
+ }
+ 
+ /* Return 1 iff there is a loop_begin note between loop_start and loop_end
+    otherwise return 0 */
+ 
+ static int
+ loop_contains_loop (loop_start, loop_end)
+      rtx loop_start;
+      rtx loop_end;
+ {
+   rtx insn;
+ 
+   insn = NEXT_INSN (loop_start);
+   while (insn && insn != loop_end)
+     {
+       if (GET_CODE (insn) == NOTE
+ 	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+ 	{
+ 	  return (1);
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   return (0);
+ }
+ 
+ 
+ /* reload_slots[indx] is a reload slot that was never updated in loop
+    but could not be lifted only because the register it is
+    loaded into was also set to something else in loop.
+    Lets see if the reload slot was set in the basic block
+    just prior to the loop by some inexpensive operation.
+    (particularly a move from memory into a register and
+    a move of that register onto stack). If so lets
+    replace each load of the reload slot in the loop with
+    a load of the memory and delete the code that loaded
+    and spilled it outside the loop.
+    This corrects the preloading of loop invariants that
+    could not be held in registers over the loop
+  */
+ static
+ void 
+ push_load_into_loop (loop_start, loop_end, indx)
+      rtx loop_start;
+      rtx loop_end;
+      int indx;
+ {
+   rtx insn, insn_sets_reload_slot, val_in_reload_slot, insns_deleted[2],
+     update_log_links_start, rn, prev, link;
+   int rindx, i, found_set, num_deleted;
+ 
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "\nTry to push load of pseudo %d into loop\n",
+ 	       reload_slots[indx].stack_slot_pseudo_reg);
+     }
+   /* Look for insn before the loop that sets this reload slot */
+   insn = PREV_INSN (loop_start);
+   insn_sets_reload_slot = 0;
+   while (insn && !insn_sets_reload_slot)
+     {
+       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN 
+ 	  || GET_CODE (insn) == CODE_LABEL 
+ 	  || (GET_CODE (insn) == NOTE
+ 	       && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 
+ 	           || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
+ 	          )
+ 	     ) 
+ 	  || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) != SET))
+ 	{
+ 	  break;
+ 	}
+       else if (GET_CODE (insn) == INSN 
+ 	       && rtx_equal_p (SET_DEST (PATTERN (insn)), reload_slots[indx].reload_stack_slot))
+ 	{
+ 	  insn_sets_reload_slot = insn;
+ 	}
+       insn = PREV_INSN (insn);
+     }
+   if (!insn_sets_reload_slot)
+     {
+       return;
+     }
+   /* Now see if the source is a register and that register is
+      set by the immediately preceeding insn - then source of
+      the immediately preceeding insn is the value in the reload
+      slot throughout the loop */
+   if (GET_CODE (SET_SRC (PATTERN (insn_sets_reload_slot))) == REG 
+       && GET_CODE (PREV_INSN (insn_sets_reload_slot)) == INSN 
+       && GET_CODE (PATTERN (PREV_INSN (insn_sets_reload_slot))) == SET 
+       && rtx_equal_p (SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot))),
+ 		   SET_SRC (PATTERN (insn_sets_reload_slot))))
+     {
+       val_in_reload_slot = SET_SRC (PATTERN (PREV_INSN (insn_sets_reload_slot)));
+     }
+   else
+     {
+       return;
+     }
+   if (is_a_reload_stack_slot (val_in_reload_slot, &rindx, cur_stack_offset, 0))
+     { /* Don't want to handle these */
+       return;
+     }
+   /* Now make sure that this value is not changed in loop */
+   if (GET_CODE (val_in_reload_slot) != MEM || !invariant_p (val_in_reload_slot))
+     {
+       return;
+     }
+   for (i = loop_store_mems_idx - 1; i >= 0; i--)
+     {
+       if (true_dependence (loop_store_mems[i], val_in_reload_slot) 
+ 	  && !is_a_reload_stack_slot (loop_store_mems[i], &rindx, cur_stack_offset, 0)
+ 	)
+ 	{
+ 	  return;
+ 	}
+     }
+   /* Now we know that the value can be substituted and that the store into
+      the reload slot outside the loop (i.e. insn_sets_reload_slot)
+      can be deleted.
+      we also want to delete the load of the reload slot
+      (i.e PREV_INSN(insn_sets_reload_slot)). we can do this if the register
+      loaded (i.e. SET_DEST(PATTERN(PREV_INSN(insn_sets_reload_slot))) is
+      set before used after PREV_INSN(insn_sets_reload_slot))
+   */
+   insn = NEXT_INSN (insn_sets_reload_slot);
+   found_set = 0;
+   while (!found_set && insn && insn != loop_end)
+     {
+       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN 
+ 	  || (GET_CODE (insn) == CODE_LABEL && PREV_INSN (insn) != loop_start))
+ 	{
+ 	  break;
+ 	}
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  if (reg_overlap_mentioned_p (
+ 		     SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot))),
+ 					PATTERN (insn)))
+ 	    {
+ 	      break;
+ 	    }
+ 	  if (GET_CODE (PATTERN (insn)) == SET 
+ 	      && rtx_equal_p (SET_DEST (PATTERN (insn)),
+ 		    SET_DEST (PATTERN (PREV_INSN (insn_sets_reload_slot)))))
+ 	    {
+ 	      found_set = 1;
+ 	    }
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   /* Do the replacement throughout the loop */
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "replacing reload slot %d with: throughout loop\n",
+ 	       indx);
+ 	  tdebug_rtx (val_in_reload_slot, loop_dump_stream);
+     }
+   insn = NEXT_INSN (insn_sets_reload_slot);
+   while (insn != loop_end)
+     {
+       if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN 
+ 	  || GET_CODE (insn) == JUMP_INSN)
+ 	{
+           init_undo_buf ();
+ 	  subst_in_insn (insn, PATTERN (insn),
+ 			 reload_slots[indx].reload_stack_slot,
+ 			 val_in_reload_slot, 1, 0);
+ 
+ 	}
+       insn = NEXT_INSN (insn);
+     }
+   insns_deleted[0] = NULL;
+   insns_deleted[1] = NULL;
+   num_deleted = 0;
+   update_log_links_start = PREV_INSN (insn_sets_reload_slot);
+   if (found_set)
+     {
+       if (loop_dump_stream)
+ 	{
+ 	  fprintf (loop_dump_stream, " delete insn %d\n",
+ 		   INSN_UID (PREV_INSN (insn_sets_reload_slot)));
+ 	}
+       insns_deleted[num_deleted++] = PREV_INSN (insn_sets_reload_slot);
+       delete_insn (PREV_INSN (insn_sets_reload_slot));
+     }
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, " delete insn %d\n",
+ 	       INSN_UID (insn_sets_reload_slot));
+     }
+   insns_deleted[num_deleted++] = insn_sets_reload_slot;
+   delete_insn (insn_sets_reload_slot);
+   /* Remove these deleted insns from any log links they are on */
+   for (rn = update_log_links_start; rn != loop_start; rn = NEXT_INSN (rn))
+     {
+       if ((GET_CODE (rn) == INSN || GET_CODE (rn) == JUMP_INSN
+ 	   || GET_CODE (rn) == CALL_INSN) && LOG_LINKS (rn))
+ 	{
+ 	  for (prev = 0, link = LOG_LINKS (rn); link;
+ 	       prev = link, link = XEXP (link, 1))
+ 	    {
+ 	      if (XEXP (link, 0) == insns_deleted[0] 
+ 		  || (num_deleted == 2 && XEXP (link, 0) == insns_deleted[1]))
+ 		{
+ 		  if (prev)
+ 		    XEXP (prev, 1) = XEXP (link, 1);
+ 		  else
+ 		    LOG_LINKS (rn) = XEXP (link, 1);
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ void
+ init_undo_buf ()
+ {
+   undobuf.storage = (char *) oballoc (0);
+   undobuf.num_undo = 0;
+ }
+ 
+ /* In pat of insn replace org with new. If not_dest is 1 then
+    don't do the rplacement if org is ae destination of a SET
+ */
+ void 
+ subst_in_insn (insn, pat, org, new, not_dest, is_dest)
+      rtx insn, pat, org, new;
+      int not_dest;
+      int is_dest;
+ {
+   inner_subst_in_insn (insn, pat, &pat, org, new, not_dest, is_dest);
+ }
+ 
+ /* In pat of insn replace org with new. If not_dest is 1 then
+    don't do the rplacement if org is ae destination of a SET
+ */
+ static void 
+ inner_subst_in_insn (insn, pat, where, org, new, not_dest, is_dest)
+      rtx insn, pat, org, new, *where;
+      int not_dest;
+      int is_dest;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+ 
+   if (not_dest && is_dest)
+     {
+       return;
+     }
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return ;
+ 
+ 
+     }
+ 
+   if (rtx_equal_p (pat, org))
+     {
+       LOOP_SUBST (where, new);
+       return;
+     }
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if (not_dest && code == SET && i == 0)
+           is_dest = 1;
+         else
+           is_dest = 0;
+         if( XEXP (pat, i))
+           inner_subst_in_insn (insn, XEXP (pat, i), &XEXP (pat, i), org, new, not_dest, is_dest);
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  inner_subst_in_insn (insn, XVECEXP (pat, i, j), &XVECEXP (pat, i, j), org, new, not_dest, 0);
+       }
+ }
+ 
+ 
+ /* tsl - begin */
+ 
+ /* Indexed by i, each entry indicates the last memory, register i was loaded
+    with, in the current loop (NULL if no reload until now) */
+    
+ static rtx last_reloads[FIRST_PSEUDO_REGISTER];
+ 
+ #define LAST_RELOAD(REGNO) last_reloads[(REGNO)]
+ 
+ /* If entry > 0 then the higher it is the less recently used it is.  
+    If entry == 0 then that register number has not been used as reload
+    since last lable.  
+  */
+ 
+ static int reload_priority[FIRST_PSEUDO_REGISTER];
+ 
+ /* Set of registers that are free and ready to be used at this moment.  */
+ 
+ extern HARD_REG_SET free_regs;
+ 
+ extern void update_free_regs (rtx);
+ extern int find_free_reg (enum machine_mode);
+ static int find_last_reload (rtx);
+ 
+ /* Replaces the reload registers of reload insns as follows:
+ 
+    for each insn which loads memory into a register,
+    if the reload register is loaded with a memory, which was previously
+    loaded, and the reload register dies in the next insn, we
+    replace the reload register, with that already loaded with the stack slot
+    (assuming that register is free - we use the same free register scanning
+    method of the memory_simplify() function). 
+    If the reload register was already used since the last label or call then
+    try to find a free register which was used less recently and replace the
+    reload register with the register found.  
+    */
+ 
+ void
+ replace_reload_registers (f, file)
+      rtx f;
+      FILE *file;
+ {
+   HARD_REG_SET saved_free_regs; /* for testing find_free_regs_between () */
+ 
+   /* indicate wheter we are in a loop now */
+ 
+   int in_loop_f = 0;
+   int save_code;
+   int i;
+ 
+   /* make flow_analysis without changing the insns and saving the pseudo
+      registers information in basic_block_live_at_start */
+ 
+   hard_reg_flow_analysis (f, file, 1 /* save pseudo register information */);
+   have_flow_analysis = 1;
+   bzero (last_reloads, sizeof last_reloads);
+ 
+   if (n_basic_blocks > 0)
+     {
+       register int regno, block;
+ 
+       /* To determine which registers are live after any insn, start from
+ 	 the beginning of the basic block and scan insns, noting
+          which registers are set by each insn and which die there. */
+ 
+       for (block = 0; block < n_basic_blocks; block++)
+ 	{
+ 	  register rtx insn;
+ 	  int end_of_block_f;
+ 
+ 	  if (file)
+ 	    fprintf (file, "\nblock number: %d:\n", block);
+ 
+ 	  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ 	    /* at the beginning of a block, each non-live hard register is
+ 	       considered free. */
+ 	    {
+ 	      register int offset = regno / REGSET_ELT_BITS;
+ 	      register int bit = 1 << (regno % REGSET_ELT_BITS);
+ 	      if (basic_block_live_at_start[block][offset] & bit)
+ 		CLEAR_HARD_REG_BIT (free_regs, regno);
+ 	      else
+ 		SET_HARD_REG_BIT (free_regs, regno);
+ 	    }
+ 
+ 	  end_of_block_f = 0;	/* signals the end of block reached */
+ 
+ 	  /* Traverse the block, an insn by insn.  Maintain a history
+ 	     of free registers and registers used to load memory
+ 	     for use only in next insn (these are called reload_registers).  
+ 	     At CALLs and CODE_LABELs restart the history of reload_registers.
+ 	  */
+ 
+ 	  for (insn = basic_block_head[block];
+ 	       ! end_of_block_f;
+ 	       insn = NEXT_INSN (insn))
+ 	    {
+ 	      rtx note, next, pat;
+ 	      rtx loop_start; /* use to test find_free_regs_between () */
+ 	      int regno;
+ 
+ 	      if (GET_CODE (insn) == CALL_INSN)
+ 		{
+ 	          bzero (last_reloads, sizeof last_reloads);
+ 	          bzero (reload_priority, sizeof reload_priority);
+ 	        }
+ 	      if (GET_CODE (insn) == CODE_LABEL)
+ 		{
+ 	          bzero (last_reloads, sizeof last_reloads);
+ 	          bzero (reload_priority, sizeof reload_priority);
+ 	          loop_start = insn;
+ 	          if (GET_CODE (PREV_INSN (insn)) == NOTE
+ 	              && NOTE_LINE_NUMBER (PREV_INSN (insn)) 
+ 	                == NOTE_INSN_LOOP_BEG)
+ 	            {
+ 	              in_loop_f = 1;
+ 	              saved_free_regs = free_regs;
+ 	            }
+ 	        }
+ 	      if (GET_CODE (insn) == JUMP_INSN
+ 		  && GET_CODE (NEXT_INSN (insn)) == NOTE
+ 		  && NOTE_LINE_NUMBER (NEXT_INSN (insn)) == NOTE_INSN_LOOP_END)
+ 		{
+ 		  register int regno;
+ #if 0
+ 	          if (in_loop_f)
+ 		    {
+ 		      find_free_regs_between (& saved_free_regs,
+ 		  			      loop_start,
+ 		  			      insn);
+ 		      if (file)
+ 		        {
+ 		          fprintf (file,
+ 		      	           "free regs found in loop (insns %d - %d): ",
+ 		      	           INSN_UID (loop_start), INSN_UID (insn));
+ 		          for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ 		            if (TEST_HARD_REG_BIT (saved_free_regs, regno))
+ 		              fprintf (file, "%d ", regno);
+ 		          fprintf (file, "\n");
+ 		        }
+ 		    }
+ #endif
+ 		  in_loop_f = 0;
+ 		}
+ 	    
+ 	      if (/*in_loop_f*/ 1)
+ 	        {
+ 		  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ 		      /*&& RTX_IS_SPILL_P (insn)*/
+ 		      && (pat = PATTERN (insn))
+ 	              && GET_CODE (pat) == SET
+ 	              && GET_CODE (SET_DEST (pat)) == REG
+ 	              && GET_CODE (SET_SRC (pat)) == MEM)
+ 	            {
+ 	              regno = REGNO (SET_DEST (pat));
+ 
+ 	              if ((next = next_nonnote_insn (insn))
+ 	                  && GET_CODE (next) == INSN
+ 	                  && (note = find_regno_note (next,
+ 						      REG_DEAD,
+ 						      regno)))
+ 			{
+ 			  /* look for new_regno to replace with */
+ 		          int new_regno = find_last_reload (SET_SRC (pat));
+ 		          enum machine_mode mode = GET_MODE (SET_DEST (pat));
+ 
+                           /* tevid */
+                           if (new_regno != FIRST_PSEUDO_REGISTER)
+                             { /* The mode must be ok */
+                               if (!HARD_REGNO_MODE_OK (new_regno, mode))
+                                 new_regno = FIRST_PSEUDO_REGISTER;
+                             }
+ 		          if (new_regno == FIRST_PSEUDO_REGISTER
+ 			      || ! TEST_HARD_REG_BIT (free_regs, new_regno))
+ 			    if (/*LAST_RELOAD (regno)*/
+ 			        reload_priority[regno])
+ 			      /* if we already used regno for reload in this
+ 			         loop it is better to reload the new memory
+ 			         to another register (if we find free one) */
+ 			      {
+ 			        new_regno = find_free_reg (mode);
+ 			        if (reload_priority [new_regno] &&
+ 			            reload_priority [regno] >=
+ 			            reload_priority [new_regno])
+ 			          {
+ 			            new_regno = FIRST_PSEUDO_REGISTER;
+ 			          }
+ 			      }
+ 			    else
+ 			      /* this is the first time we're using this
+ 			         register for reload in the current loop -
+ 			         so we need no replacement */
+ 			      new_regno = FIRST_PSEUDO_REGISTER;
+ 
+ 
+ 
+ 
+ 
+ 			  if (new_regno != FIRST_PSEUDO_REGISTER
+ 			      /* if regno == new_regno no replcement needed */
+ 			      && new_regno != regno)
+ 	                    {
+ 	                      register int nregs, i;
+ 	                      int stop_replacement = 0;
+ 
+ 		              rtx new_reg = gen_rtx (REG, mode, new_regno);
+ 	                      rtx old_reg = XEXP (note, 0);
+ 
+ 		              /* replace this register in the next insn */
+                               init_undo_buf ();
+ 		              subst_in_insn (next,
+ 		    		             PATTERN (next),
+ 		    		             old_reg,
+ 		    		             new_reg,
+ 		    		             0,
+ 		    		             0);
+ 
+ #ifdef REGISTER_CONSTRAINTS
+                               save_code = INSN_CODE (next);
+ 
+ 	                      if ((INSN_CODE (next) = recog (PATTERN (next),
+ 							     next,
+ 							     0)) != -1)
+ 		                insn_extract (next);
+ 
+ 		              if (INSN_CODE (next) == -1
+ 		                  || !constrain_operands (INSN_CODE (next), 1))
+ 		                {
+ 			          /* restore the previous situation */
+ 			          INSN_CODE (next) = save_code;
+ 			          loop_undo_all ();
+ 		                  /*subst_in_insn (next,
+ 		    		                 PATTERN (next),
+ 		    		                 new_reg,
+ 		    		                 old_reg,
+ 		    		                 0,
+ 		    		                 0);*/
+ 		                  stop_replacement = 1;
+  		                }
+ #endif
+  		              if (! stop_replacement)
+  		                {
+  		                  rtx next_dest = SET_DEST (PATTERN (next));
+ 
+ 	                          /* replace this insn's register with regno */
+ 	                          SET_DEST (pat) = new_reg;
+ #if 0
+                                   init_undo_buf ();
+ 		    	          subst_in_insn (next,
+ 						 note,
+ 						 old_reg,
+ 						 new_reg,
+ 						 0,
+ 						 0);
+ #endif
+ 
+ 				  /* The regno in the REG_DEAD note should be
+ 				     changed */
+ 
+ 				  XEXP (note, 0) = new_reg;
+ 		          
+ 				  /* Now, if we replaced a REG_DEAD note, and
+ 				     the new_reg is the destination of the next
+ 				     insn, we should remove this note */
+ 				  /* tevid replaced regno with new_regno,
+ 				     twice */
+ 
+ 				  if (GET_CODE (next_dest) == REG
+ 				      && REGNO (next_dest) == new_regno)
+ 				    remove_death (new_regno, next);
+ 			  
+ 				  /* replace the registers in the free_register
+ 				     list */
+ 				  nregs = HARD_REGNO_NREGS (new_regno, mode);
+ 				  for (i = 0; i < nregs; i++)
+ 				    CLEAR_HARD_REG_BIT (free_regs, new_regno + i);
+ 				  nregs = HARD_REGNO_NREGS (regno, mode);
+ 				  for (i = 0; i < nregs; i++)
+ 				    SET_HARD_REG_BIT (free_regs, regno + i);
+ 
+ 				  if (file)
+ 				    {
+ 				      fprintf (file, "insn %d: reload register",
+ 							       INSN_UID (insn));
+ 				      fprintf (file, " replaced (old %d new %d)\n",
+ 				      regno, new_regno);
+ 				    }
+ #ifdef REGISTER_CONSTRAINTS
+ 				}  /* if (! stop_replacement) */
+ #endif
+ 
+ 			    }  /* if (new_regno != FIRST_PSEUDO_REGISTER
+ 			    	      && new_regno != regno) */
+ 
+ 			    else if (file)
+ 			       {
+ 			         fprintf (file, "insn %d: no free register for",
+ 							       INSN_UID (insn));
+ 				 fprintf (file, " reload replacement\n");
+ 			       }
+ 			}  /* if (next = next_nonnote (insn))
+ 				  && (note = find_regno_note (next,
+ 				  			      REG_DEAD,
+ 				  			      regno))) */
+ 		      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 		        if (reload_priority[i] > 0)
+ 		          reload_priority[i]++;
+ 		      reload_priority[REGNO (SET_DEST (PATTERN (insn)))] = 1;
+ 	            }  /* if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ 		              && RTX_IS_SPILL_P (insn)
+ 		              && (pat = PATTERN (insn))
+ 	                      && GET_CODE (pat) == SET
+ 	                      && GET_CODE (SET_DEST (pat)) == REG */
+ 
+ 		  /* update the last_reloads array */
+ 
+ 		  if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
+ 		      && (pat = PATTERN (insn))
+ 	              && GET_CODE (pat) == SET
+ 	              && GET_CODE (SET_DEST (pat)) == REG
+ 	              && GET_CODE (SET_SRC (pat)) == MEM)
+ 	            LAST_RELOAD (REGNO (SET_DEST (pat ))) = SET_SRC (pat);
+ 
+ 	        }  /* if (in_loop_f) */
+ 
+ 	      end_of_block_f = (insn == basic_block_end[block]);
+ 
+ 	      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ 	        {
+ 	          register int j;
+ 	          rtx set;
+ 
+ 	          if (GET_CODE (insn) == CALL_INSN)
+ 		    /* all call clobbered registers are now free */
+ 		    for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ 		      if (call_used_regs[j])
+ 		        SET_HARD_REG_BIT (free_regs, j);
+ 
+ 		  update_free_regs (PATTERN (insn));
+ 
+ 		  /* Update LAST_RELOADs that are no longer valid */
+ 		  update_last_reloads ( PATTERN (insn));
+ 		     
+ 
+ 		  /* add each dead register to the free_regs set */
+ 		  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ 		    if ((REG_NOTE_KIND (note) == REG_DEAD
+ 		         || REG_NOTE_KIND (note) == REG_UNUSED)
+ 		        && GET_CODE (XEXP (note, 0)) == REG)
+ 		      {
+ 			register int i;
+ 		        register int regno = REGNO (XEXP (note, 0));
+ 		        register int nregs = 
+ 			    HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0)));
+ 
+ 		        for (i = 0; i < nregs; i++)
+ 			  SET_HARD_REG_BIT (free_regs, regno + i);
+ 		      }
+ 		  if ((note = find_reg_note (insn, REG_WAS_0, 0)))
+ 		    {
+ 		      set = single_set (insn);
+ 		      if (set == NULL 
+ 		          || GET_CODE (SET_DEST (set)) == REG)
+ 		        { /* Since reg may have been reused.  */
+ 		          remove_note (insn, note);
+ 		        }
+ 		    }
+ 		}
+ 
+ 	    }  /* for (insn = basic_block_head[block]; */
+ 	}  /* for (block = 0; block < n_basic_blocks; block++) */
+     }  /* if (n_basic_blocks > 0) */
+ }  /* replace_reload_registers (file, f) */
+ 
+ 
+ 
+ /* Returns a hard register regno, if the contents of entry regno in
+    last_reloads array equals to MEM, FIRST_PSEUDO_REGISTER otherwise. */
+ 
+ static int
+ find_last_reload (rtx mem)
+ {
+   register int regno;
+   
+   if (GET_CODE (mem) != MEM)
+     abort ();
+ 
+   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+     /* tevid added test of LAST_RELOAD (regno) != NULL and XEXPs */
+     if (LAST_RELOAD (regno) != NULL
+         && rtx_equal_p (XEXP (LAST_RELOAD (regno), 0), XEXP (mem, 0)))
+       return (regno);
+ 
+   return (FIRST_PSEUDO_REGISTER);
+ }
+ 
+ /* Keep track of effect of pat on last_reloads[]. Note that making
+    an error will not effect the correctness of the code.  */
+    
+ static void
+ update_last_reloads (rtx pat)
+ {
+   register int i, j, regno, nregs;
+   rtx set_src, set_dest;
+   register char *fmt;
+   register RTX_CODE code = GET_CODE (pat);
+ 
+   switch (GET_CODE (pat))
+     {
+       case SET:
+       case CLOBBER:
+         set_dest = SET_DEST (pat);
+         if (GET_CODE (set_dest) == REG)
+           {
+             regno = REGNO (set_dest);
+             nregs = HARD_REGNO_NREGS (regno, GET_MODE (set_dest));
+ 
+             if (nregs != 1)
+               {
+ 	        bzero (last_reloads, sizeof last_reloads);
+               }
+             else
+               {
+                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+                   {
+                     if (LAST_RELOAD (i))
+                       {
+                         if (reg_overlap_mentioned_p (set_dest, LAST_RELOAD (i)))
+                           {
+                             LAST_RELOAD (i) = NULL;
+                           }
+                       }
+                   }
+               }
+           }
+         else if (GET_CODE (set_dest) == SUBREG)
+           {
+             if (GET_CODE (SUBREG_REG (set_dest)) == REG)
+               {
+                 regno = REGNO (SUBREG_REG (set_dest)) + SUBREG_WORD (set_dest);
+                 nregs 
+                   = HARD_REGNO_NREGS (regno, GET_MODE (SUBREG_REG (set_dest)));
+ 
+                 if (nregs != 1)
+                   {
+ 	            bzero (last_reloads, sizeof last_reloads);
+                   }
+                 else
+                   {
+                     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+                       {
+                         if (LAST_RELOAD (i))
+                           {
+                             if (reg_overlap_mentioned_p (SUBREG_REG (set_dest), 
+                             LAST_RELOAD (i)))
+                               {
+                                 LAST_RELOAD (i) = NULL;
+                               }
+                           }
+                       }
+                   }
+               }
+             return;
+           }
+         else if (GET_CODE (set_dest) == MEM)
+           {
+ 	    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ 	      if (LAST_RELOAD (i)
+ 	          && true_dependence (set_dest, LAST_RELOAD (i)))
+ 	        LAST_RELOAD (i) = 0;
+ 	    update_last_reloads (XEXP (set_dest, 0));
+             return;
+           }
+       case CALL:
+ 	for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ 	  if (call_used_regs[j])
+ 	    LAST_RELOAD (j) = NULL;
+         return;
+       case PRE_DEC:
+       case PRE_INC:
+       case POST_DEC:
+       case POST_INC:
+         if (GET_CODE (XEXP (pat ,0)) == REG)
+           {
+             regno = REGNO (XEXP (pat ,0));
+             nregs = HARD_REGNO_NREGS (regno, GET_MODE (XEXP (pat ,0)));
+ 
+             if (nregs != 1)
+               {
+ 	        bzero (last_reloads, sizeof last_reloads);
+               }
+             else
+               {
+                 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+                   {
+                     if (LAST_RELOAD (i))
+                       {
+                         if (reg_overlap_mentioned_p (XEXP (pat ,0), LAST_RELOAD (i)))
+                           {
+                             LAST_RELOAD (i) = NULL;
+                           }
+                       }
+                   }
+               }
+           }
+         return;
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+     case REG:
+     /*case SUBREG:*/
+         /* do nothing */
+         return;
+   }  /* switch (GET_CODE (pat)) */
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if( XEXP (pat, i))
+           update_last_reloads (XEXP (pat, i));
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  update_last_reloads (XVECEXP (pat, i, j));
+       }
+ }  
+ 
+ /* tsl - end */
+ 
+ static unsigned int largest_himode_const;
+ 
+ #define MAX_COMP_REGS 4
+ 
+ struct sign_extension_info {
+   rtx insn_set;
+   int num_comp_regs;
+   struct comp_to_reg {
+     int regno;
+     rtx comp_insn;
+     rtx *where;
+     unsigned char for_equality;
+   } compare_to_reg [MAX_COMP_REGS];
+ };
+ static struct sign_extension_info * sign_extension_infos;
+ 
+ static void
+ sign_extension_reduction (loop_start, loop_end)
+   rtx loop_start, loop_end;
+ {
+   int cur_max_regnum = max_reg_num ();
+   int found_sign_extension = 0, regno, i, j;
+   rtx insn, sign_ext_reg;
+ 
+   sign_extension_infos 
+     = (struct  sign_extension_info *) 
+       alloca ( sizeof (struct sign_extension_info) * cur_max_regnum);
+   bzero (sign_extension_infos, 
+          sizeof (struct sign_extension_info) * cur_max_regnum);
+   largest_himode_const = 256;
+   if (sizeof (unsigned int) <= GET_MODE_SIZE (HImode))
+     {
+       return ;
+     }
+   for (i = 0; i < GET_MODE_SIZE (HImode); i++)
+     {
+       largest_himode_const *= 256;
+     }
+   largest_himode_const -= 1;
+   /* Go over loop - mark registers set by sign extension */
+   for (insn = loop_start; insn && insn != loop_end; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
+           && GET_CODE (SET_DEST (PATTERN (insn))) == REG 
+           && GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND
+           && GET_MODE (SET_DEST (PATTERN (insn))) == SImode
+           && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode)
+          { /* Found one.  */
+            regno = REGNO (SET_DEST (PATTERN (insn)));
+            if ( regno >= cur_max_regnum)
+              {
+                return;
+              }
+            found_sign_extension++;
+            if (sign_extension_infos[regno].insn_set)
+              {
+                return;
+              }
+            sign_extension_infos[regno].insn_set = insn;
+          }
+     }
+   if (!found_sign_extension || insn != loop_end)
+     {
+       return;
+     }
+   /* Find all uses of each register marked above */
+   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
+     {
+       if (sign_extension_infos[i].insn_set)
+         {
+           for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
+             {
+               if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
+                   || GET_CODE (insn) == JUMP_INSN)
+                 {
+                   
+                   validate_all_references (i, insn, PATTERN (insn));
+                 }
+             }
+         }
+     }
+   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
+     {
+       if (sign_extension_infos[i].insn_set)
+         {
+           sign_ext_reg = SET_DEST (PATTERN (sign_extension_infos[i].insn_set));
+           if (reg_used_between_p (sign_ext_reg,
+                                   get_insns (), loop_start) ||
+               reg_used_between_p (sign_ext_reg,
+                                   loop_end, NULL)
+              )
+             {
+               sign_extension_infos[i].insn_set = NULL;
+             }
+         }
+     }
+   /* Check which registers can be sign extension reduced */
+   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
+     {
+       if (sign_extension_infos[i].insn_set)
+         {
+           j = 0;
+           while (j < sign_extension_infos[i].num_comp_regs
+                  && sign_extension_infos[i].insn_set)
+             {
+               regno = sign_extension_infos[i].compare_to_reg[j].regno;
+               if (regno < FIRST_PSEUDO_REGISTER)
+                 {
+                   sign_extension_infos[i].insn_set = NULL;
+                 }
+               if (sign_extension_infos[regno].insn_set == NULL)
+                 {
+                   sign_extension_infos[i].insn_set = NULL;
+                 }
+               j++;
+             }
+         }
+     }
+   /* Do the optimization.  */
+   for (i = FIRST_PSEUDO_REGISTER; i < cur_max_regnum; i++)
+     {
+       if (sign_extension_infos[i].insn_set)
+         {
+           rtx subreg, strict_subreg;
+ 
+           subreg 
+             = gen_rtx (SUBREG, HImode, 
+               SET_DEST (PATTERN (sign_extension_infos[i].insn_set)),
+               0);
+           strict_subreg = gen_rtx (STRICT_LOW_PART, 0, subreg);
+           emit_insn_before (gen_rtx (SET, 0, 
+              SET_DEST (PATTERN (sign_extension_infos[i].insn_set)),
+              const0_rtx), loop_start);
+           emit_insn_before (gen_rtx (USE, 0, 
+              SET_DEST (PATTERN (sign_extension_infos[i].insn_set))),
+              loop_start);
+           SET_DEST (PATTERN (sign_extension_infos[i].insn_set)) 
+             = strict_subreg;
+           SET_SRC (PATTERN (sign_extension_infos[i].insn_set)) 
+             = XEXP (SET_SRC (PATTERN (sign_extension_infos[i].insn_set)), 0);
+           INSN_CODE (sign_extension_infos[i].insn_set) = -1;
+           j = 0;
+           while (j < sign_extension_infos[i].num_comp_regs)
+             {
+               if (sign_extension_infos[i].compare_to_reg[j].for_equality == 0)
+                 {
+                   *sign_extension_infos[i].compare_to_reg[j].where
+                     = subreg;
+                   INSN_CODE (sign_extension_infos[i].compare_to_reg[j].comp_insn)
+                     = -1;
+                 }
+               j++;
+             }
+         }
+     }
+ }
+ 
+ 
+ static void
+ validate_all_references (regno, insn, pat)
+   int regno;
+   rtx insn, pat;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j, val;
+   register char *fmt;
+   int num_comp_regs, comp_regno, for_equality = 0;
+   rtx next;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return ;
+ 
+     case REG:
+       if (REGNO (pat) == regno)
+         {
+           sign_extension_infos[regno].insn_set = NULL;
+         }
+       break;
+       
+     case SET:
+       if (GET_CODE (SET_DEST (pat)) == REG 
+           && REGNO (SET_DEST (pat)) == regno
+           && sign_extension_infos[REGNO (SET_DEST (pat))].insn_set != insn)
+         {
+           if (GET_CODE (SET_SRC (pat)) != CONST_INT)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           if (GET_MODE (SET_DEST (pat)) != SImode)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           val = XINT (SET_SRC (pat), 0);
+           if (val < 0 || val > largest_himode_const)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           validate_all_references (regno, insn, SET_SRC (pat));
+           return;
+         }
+       else if (GET_CODE (SET_DEST (pat)) == REG 
+           && REGNO (SET_DEST (pat)) == regno
+           && sign_extension_infos[REGNO (SET_DEST (pat))].insn_set == insn)
+         {
+           return;
+         }
+       break;
+ 
+     case AND:
+       if (GET_CODE (XEXP (pat, 0)) == REG 
+           && REGNO (XEXP (pat, 0)) == regno)
+         {
+           if (GET_CODE (XEXP (pat, 1)) != CONST_INT)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           if (GET_MODE (XEXP (pat, 0)) != SImode)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           val = XINT (XEXP (pat, 1), 0);
+           if (val < 0 || val > largest_himode_const)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           validate_all_references (regno, insn, XEXP (pat, 1));
+           return;
+         }
+       else if (GET_CODE (XEXP (pat, 1)) == REG 
+           && REGNO (XEXP (pat, 1)) == regno)
+         {
+           if (GET_CODE (XEXP (pat, 0)) != CONST_INT)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           if (GET_MODE (XEXP (pat, 1)) != SImode)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           val = XINT (XEXP (pat, 0), 0);
+           if (val < 0 || val > largest_himode_const)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           validate_all_references (regno, insn, XEXP (pat, 0));
+           return;
+         }
+       break;
+ 
+     case COMPARE:
+       next = NEXT_INSN (insn);
+       if (GET_CODE (next) == JUMP_INSN 
+ 	  && GET_CODE (PATTERN (next)) == SET 
+ 	  && SET_DEST (PATTERN (next)) == pc_rtx 
+ 	  && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE
+ 	  && (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
+ 	      ||
+ 	      GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ))
+ 	{
+ 	  for_equality = 1;
+ 	}
+       if (GET_CODE (XEXP (pat, 0)) == REG 
+           && REGNO (XEXP (pat, 0)) == regno)
+         {
+           if (GET_MODE (XEXP (pat, 0)) != SImode)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           if (GET_CODE (XEXP (pat, 1)) == CONST_INT)
+             {
+               val = XINT (XEXP (pat, 1), 0);
+               if (for_equality == 0 || val < 0 || val > largest_himode_const)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+             }
+           else if (GET_CODE (XEXP (pat, 1)) == REG)
+             {
+               if (GET_MODE (XEXP (pat, 1)) != SImode)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+ #ifndef HAVE_cmphi
+               sign_extension_infos[regno].insn_set = NULL;
+ #else
+               if (!HAVE_cmphi)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+ #endif
+               comp_regno = REGNO (XEXP (pat, 1));
+               if (!sign_extension_infos[comp_regno].insn_set)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+               else
+                 {
+                   num_comp_regs 
+                     = sign_extension_infos[regno].num_comp_regs;
+                   if (num_comp_regs >= MAX_COMP_REGS)
+                     {
+                       sign_extension_infos[regno].insn_set = NULL;
+                     }
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].where = 
+                     &XEXP (pat, 0);
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].comp_insn = insn;
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].regno = 
+                     comp_regno;
+ 	          sign_extension_infos[regno].
+ 	             compare_to_reg[num_comp_regs].for_equality = for_equality;
+                   sign_extension_infos[regno].num_comp_regs++;
+                 }
+             }
+           else
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+               validate_all_references (regno, insn, XEXP (pat, 1));
+             }
+           return;
+         }
+       else if (GET_CODE (XEXP (pat, 1)) == REG 
+           && REGNO (XEXP (pat, 1)) == regno)
+         {
+           if (GET_MODE (XEXP (pat, 1)) != SImode)
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+             }
+           if (GET_CODE (XEXP (pat, 0)) == CONST_INT)
+             {
+               val = XINT (XEXP (pat, 0), 0);
+               if (for_equality == 0 || val < 0 || val > largest_himode_const)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+             }
+           else if (GET_CODE (XEXP (pat, 0)) == REG)
+             {
+               if (GET_MODE (XEXP (pat, 0)) != SImode)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+ #ifndef HAVE_cmphi
+               sign_extension_infos[regno].insn_set = NULL;
+ #else
+               if (!HAVE_cmphi)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+ #endif
+               comp_regno = REGNO (XEXP (pat, 0));
+               if (!sign_extension_infos[comp_regno].insn_set)
+                 {
+                   sign_extension_infos[regno].insn_set = NULL;
+                 }
+               else
+                 {
+                   num_comp_regs 
+                     = sign_extension_infos[regno].num_comp_regs;
+                   if (num_comp_regs >= MAX_COMP_REGS)
+                     {
+                       sign_extension_infos[regno].insn_set = NULL;
+                     }
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].where = 
+                     &XEXP (pat, 1);
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].comp_insn = insn;
+                   sign_extension_infos[regno].
+                       compare_to_reg[num_comp_regs].regno = 
+                     comp_regno;
+ 	          sign_extension_infos[regno].
+ 	             compare_to_reg[num_comp_regs].for_equality = for_equality;
+                   sign_extension_infos[regno].num_comp_regs++;
+                 }
+             }
+           else
+             {
+               sign_extension_infos[regno].insn_set = NULL;
+               validate_all_references (regno, insn, XEXP (pat, 0));
+             }
+           return;
+         }
+       break;
+ 
+ 
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if( XEXP (pat, i))
+           validate_all_references (regno, insn, XEXP (pat, i));
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+           validate_all_references (regno, insn, XVECEXP (pat, i, j));
+       }
+ }
+ 
+ #define MAX_WHERE 5
+ #define MAX_DISAMBIGS 3
+ #define MAX_MEM_REFS 10
+ #define NO_REG -1
+ #define UNKNOWN -2
+ 
+ static struct mem_ref {
+   /*  Pointers to where this mem_ref is used.  */
+   rtx * where[MAX_WHERE];
+   /* Number of references to this mem_ref in the loop.  */
+   int num_ref;
+   /* The base register number if any, else -1.  */
+   int base_regno;
+   /* The base register number if.  */
+   rtx base_reg;
+   /* The index register number if any, else -1.  */
+   int index_regno;
+   /* The index register number if.  */
+   rtx index_reg;
+   /* Bit-map if bit# i is set then this element is true_dependence on
+      element# i. Assumes MAX_MEM_REFS < (sizeof (int) * 8) */
+   int conflict;
+   /* If 1 then this element is a varying address over the loop - or
+      should not be lifted into register for some other reason.  */
+   unsigned int varying:1;
+   /* If 1 then this mem_ref is stored into in the loop.  */
+   unsigned int stored:1;
+   /* If 1 then the first reference to the mem_ref in the loop is a store.  */
+   unsigned int first_stored:1;
+   } *mem_refs;
+ 
+ static struct disambig{
+   rtx reg;
+   int inc_val;
+ }	runtime_disambigs [MAX_DISAMBIGS];
+ 
+ static int num_mem_refs = 0;
+ static int max_regs_before_lift;
+ 
+ extern rtx gen_jump ();
+ /*
+   Shadow memory locations that are stored into in the loop and can
+   be memory disambiguated over the loop. These are loaded into a register
+   before the loop, accessed from and into the register during the loop
+   and stored from the register at the loop end.  
+ */
+ static void
+ lift_stores (loop_start, loop_end)
+   rtx loop_start, loop_end;
+ {
+   rtx insn, lift_reg, set, new_label, new_label_insn, new_jump_insn, new_jump,
+       new_loop_label, new_loop_jump, new_compare, new_compare_insn, copy_insn;
+   int i, j, num_candidates, jmask, imask, num_lifted, num_possible,
+       indx_possible, num_runtime_disambigs, disambig_mask, found, dummy;
+   char * may_not_optimize;
+   
+   if (loop_dump_stream)
+     {
+       fprintf (loop_dump_stream, "lift stores from %d to %d\n",
+       INSN_UID (loop_start), INSN_UID (loop_end));
+     }
+   /* Handle only loops with no inner jumps labels or calls */
+   if (GET_CODE (PREV_INSN (loop_end)) != JUMP_INSN)
+     {
+       return;
+     }
+   if (GET_CODE (SET_SRC (PATTERN (PREV_INSN (loop_end)))) != IF_THEN_ELSE)
+     {
+       return;
+     }
+   if (GET_CODE (NEXT_INSN (loop_start)) != CODE_LABEL)
+     {
+       return;
+     }
+   for (insn = NEXT_INSN (NEXT_INSN (loop_start)); 
+        insn != PREV_INSN (loop_end); insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CALL_INSN
+           || GET_CODE (insn) == CODE_LABEL)
+         {
+           return;
+         }
+     }
+   /* Compute n_times_set */
+   max_regs_before_lift = max_reg_num () + 1;
+   n_times_set = (short *) alloca (max_regs_before_lift * sizeof (short));
+   bzero (n_times_set, max_regs_before_lift * sizeof (short));
+   may_not_optimize = (char *) alloca (max_regs_before_lift);	/* not used */
+   count_loop_regs_set (loop_start, loop_end, may_not_optimize, NULL,
+ 		       &dummy, max_regs_before_lift);
+ 
+   mem_refs = (struct mem_ref *) alloca (sizeof (struct mem_ref) * MAX_MEM_REFS);
+   bzero (mem_refs, sizeof (struct mem_ref) * MAX_MEM_REFS);
+   /* Locate all memory refs into the mem_refs array.  */
+   num_mem_refs = 0;
+   for (insn = loop_start; insn != loop_end; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN)
+         {
+           mark_mem_refs (PATTERN (insn), &PATTERN (insn));
+           if (num_mem_refs >= MAX_MEM_REFS)
+             {
+               return;
+             }
+         }
+     }
+   if (num_mem_refs == 0)
+     {
+       return;
+     }
+   /* Check each non varying mem_ref against all others to see if it can
+      be memory disambiguated */
+   num_candidates = 0;
+   for (i = 0; i < num_mem_refs; i++)
+     {
+       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1)
+         {
+           num_candidates++;
+           imask = 1 << i;
+           for (j = 0; j < num_mem_refs; j++)
+             {
+               jmask = (1 << j);
+               if (j != i && !(mem_refs[i].conflict & jmask))
+                 {
+                   if (true_dependence (*(mem_refs[i].where[0]),
+                                        *(mem_refs[j].where[0])))
+                     {
+                       mem_refs[i].conflict |= jmask;
+                       mem_refs[j].conflict |= imask;
+                     }
+                 }
+             }
+         }
+     }
+   /* Lift all the mem_refs that can be lifted.  */
+   num_lifted = 0;
+   num_possible = 0;
+   for (i = 0; i < num_mem_refs; i++)
+     {
+       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1)
+         {
+           num_possible++;
+           indx_possible = i;
+         }
+       if (mem_refs[i].varying == 0 && mem_refs[i].stored == 1
+           && mem_refs[i].conflict == 0)
+         {
+           num_lifted++;
+           lift_reg = gen_reg_rtx (GET_MODE (*(mem_refs[i].where[0])));
+           if (mem_refs[i].first_stored)
+             {
+               emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
+                                           CONST0_RTX ( GET_MODE (lift_reg))),
+                                  loop_start);
+             }
+           else
+             {
+               emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
+                                           copy_rtx (*(mem_refs[i].where[0]))),
+                                  loop_start);
+             }
+           emit_insn_after ( gen_rtx (SET, 0, copy_rtx (*(mem_refs[i].where[0])),
+                                               lift_reg),
+                                  loop_end);
+           /*emit_insn_after (gen_rtx (USE, 0, lift_reg),
+                           NEXT_INSN (loop_end));*/
+           for (j = 0; j < mem_refs[i].num_ref; j++)
+             {
+               *(mem_refs[i].where[j]) = lift_reg;
+             }
+           if (loop_dump_stream)
+             {
+               fprintf (loop_dump_stream, 
+               "The following memory operand lifted into reg %d during loop:\n",
+               REGNO (lift_reg));
+               tdebug_rtx (SET_DEST (PATTERN (NEXT_INSN (loop_end))),
+                           loop_dump_stream);
+               fprintf (loop_dump_stream, "\n");
+             }
+         }
+     }
+   if (num_lifted == 0 && num_possible == 1 && flag_runtime_lift_stores)
+     {  /* Do runtime disambiguation if possible */
+       if (mem_refs[indx_possible].index_regno != NO_REG
+           || mem_refs[indx_possible].base_regno == NO_REG
+           || mem_refs[indx_possible].base_regno == UNKNOWN)
+         {
+           return;
+         }
+       if (GET_MODE (mem_refs[indx_possible].base_reg) != SImode)
+         {
+           return;
+         }
+       num_runtime_disambigs = 0;
+       for (i = 0; i < num_mem_refs; i++)
+         {
+           disambig_mask = 1 << i;
+           if (mem_refs[indx_possible].conflict & disambig_mask)
+             {
+               if (num_runtime_disambigs >= MAX_DISAMBIGS)
+                 {
+                   return;
+                 }
+               if (mem_refs[i].base_regno == NO_REG 
+                   || mem_refs[i].base_regno == UNKNOWN
+                   || (mem_refs[i].index_regno != UNKNOWN
+                       && mem_refs[i].index_regno != NO_REG))
+                 {
+                   return;
+                 }
+               if (n_times_set[mem_refs[i].base_regno] > 1)
+                 {
+                   return;
+                 }
+               if (GET_MODE (mem_refs[i].base_reg) 
+                    != GET_MODE (mem_refs[indx_possible].base_reg))
+                 {
+                   return;
+                 }
+               runtime_disambigs[num_runtime_disambigs].reg
+                 = mem_refs[i].base_reg;
+               runtime_disambigs[num_runtime_disambigs].inc_val = 0;
+               num_runtime_disambigs++;
+             }
+         }
+       /* Now find the setting of each of the registers of the disambigs */
+       for (i = 0; i < num_runtime_disambigs; i++)
+         {
+           if (n_times_set[REGNO (runtime_disambigs[i].reg)])
+             {
+               insn = loop_start;
+               found = 0;
+               while (insn != loop_end && !found)
+                 {
+                   if (GET_CODE (insn) == INSN)
+                     {
+                       set = single_set (insn);
+                       if (set && GET_CODE (SET_DEST (set)) == REG
+                           && REGNO (SET_DEST (set)) 
+                               == REGNO (runtime_disambigs[i].reg) )
+                         {
+                           found = 1;
+                           if (!rtx_equal_p (SET_DEST (set),
+                                             runtime_disambigs[i].reg))
+                             {
+                               return;
+                             }
+                           if ((GET_CODE (SET_SRC (set)) == PLUS
+                                 || GET_CODE (SET_SRC (set)) == MINUS)
+                               && rtx_equal_p (SET_DEST (set), 
+                                               XEXP (SET_SRC (set), 0))
+                               && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
+                             {
+                               runtime_disambigs[i].inc_val 
+                                 = XINT (XEXP (SET_SRC (set), 1), 0) 
+                                    * (GET_CODE (SET_SRC (set)) == PLUS
+                                       ? 1 : -1);
+                             }
+                           else
+                             {
+                               return;
+                             }
+                         }
+                     }
+                   if (!found)
+                     {
+                       insn = NEXT_INSN (insn);
+                     }
+                 }
+               if (!found)
+                 {
+                   return;
+                 }
+             }
+         }
+       /* The runtime disambiguation is possible - now do it.  */
+       /* Make a copy of the loop.  */
+       new_label = gen_label_rtx ();
+       new_label_insn 
+         = emit_label_after (new_label, PREV_INSN (loop_start));
+       new_loop_label = new_label_insn;
+       ++LABEL_NUSES (new_label_insn);
+       new_jump = copy_rtx (PATTERN (PREV_INSN (loop_end)));
+       if (XEXP (SET_SRC (new_jump), 1) == pc_rtx)
+         {
+           XEXP (SET_SRC (new_jump), 2)
+             = gen_rtx (LABEL_REF, VOIDmode, new_label);
+         }
+       else
+         {
+           XEXP (SET_SRC (new_jump), 1)
+             = gen_rtx (LABEL_REF, VOIDmode, new_label);
+         }
+       new_jump_insn = emit_jump_insn_after (new_jump, new_label_insn);
+       INSN_CODE (new_jump_insn) = recog (new_jump, new_jump_insn);
+       new_loop_jump = new_jump_insn;
+       JUMP_LABEL (new_jump_insn) = new_label_insn;
+       /* The body of the original loop is moved to the new loop */
+       NEXT_INSN (new_label_insn) = NEXT_INSN (NEXT_INSN (loop_start));
+       PREV_INSN (NEXT_INSN (new_label_insn)) = new_label_insn;
+       PREV_INSN (new_jump_insn) = PREV_INSN (PREV_INSN (loop_end));
+       NEXT_INSN ( PREV_INSN (new_jump_insn)) = new_jump_insn;
+       NEXT_INSN (NEXT_INSN (loop_start)) = PREV_INSN (loop_end);
+       PREV_INSN (PREV_INSN (loop_end)) = NEXT_INSN (loop_start);
+       /* Now make a copy of the loop in between the original label and jump.  */
+       insn = NEXT_INSN (new_label_insn);
+       copy_insn = NEXT_INSN (loop_start);
+       while (insn != new_jump_insn)
+         {
+           if (GET_CODE (insn) == INSN)
+             {
+               copy_insn = emit_insn_after (copy_rtx (PATTERN (insn)), copy_insn);
+             }
+           insn = NEXT_INSN (insn);
+         }
+       /* Now make a jump around the second copy of the loop.  */
+       new_label = gen_label_rtx ();
+       new_label_insn 
+         = emit_label_after (new_label, loop_end);
+       new_jump_insn = emit_jump_insn_after (gen_jump (new_label_insn),
+           PREV_INSN (loop_start));
+       JUMP_LABEL (new_jump_insn) = new_label_insn;
+       ++LABEL_NUSES (new_label_insn);
+       emit_barrier_after (new_jump_insn);
+       /* Now make a label just before loop start */
+       new_label = gen_label_rtx ();
+       new_label_insn 
+         = emit_label_after (new_label, PREV_INSN (loop_start));
+       ++LABEL_NUSES (new_label_insn);
+       /* Now compare the base_reg of the mem_ref to be lifted with
+          each of the base_regs that it conflicts with.  Jump around the
+          disambiguated loop if they conflict at runtime.  */
+       for (i = 0; i < num_runtime_disambigs; i++)
+         {
+           if (runtime_disambigs[i].inc_val != 0)
+             {
+               new_compare 
+                 = gen_cmpsi_1 (runtime_disambigs[i].reg,
+                                 mem_refs[indx_possible].base_reg);
+               new_compare_insn 
+                 = emit_insn_before (new_compare, new_loop_label);
+               new_jump = copy_rtx (new_jump);
+               if (runtime_disambigs[i].inc_val > 0)
+                 {
+                   GET_CODE (XEXP (SET_SRC (new_jump), 0)) = LE;
+                 }
+               else
+                 {
+                   GET_CODE (XEXP (SET_SRC (new_jump), 0)) = GE;
+                 }
+ 	      XEXP (SET_SRC (new_jump), 1) 
+ 	        = gen_rtx (LABEL_REF, VOIDmode, new_label);
+ 	      XEXP (SET_SRC (new_jump), 2) = pc_rtx;
+               ++LABEL_NUSES (new_label_insn);
+               new_jump_insn 
+                 = emit_jump_insn_after (new_jump, new_compare_insn);
+               JUMP_LABEL (new_jump_insn) = new_label_insn;
+               INSN_CODE (new_jump_insn)
+                 = recog (new_jump, new_jump_insn);
+             }
+         }
+       /* Now do the lifting */
+       lift_reg = gen_reg_rtx (GET_MODE (*(mem_refs[indx_possible].where[0])));
+       if (mem_refs[indx_possible].first_stored)
+         {
+           emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
+                                       CONST0_RTX ( GET_MODE (lift_reg))),
+                              new_loop_label);
+         }
+       else
+         {
+           emit_insn_before ( gen_rtx (SET, 0, lift_reg, 
+                             copy_rtx (*(mem_refs[indx_possible].where[0]))),
+                              new_loop_label);
+         }
+       emit_insn_after ( gen_rtx (SET, 0, 
+                                  copy_rtx (*(mem_refs[indx_possible].where[0])),
+                                           lift_reg),
+                              new_loop_jump);
+       /*emit_insn_after (gen_rtx (USE, 0, lift_reg),
+                       NEXT_INSN (new_loop_jump));*/
+       emit_insn_after (gen_rtx (CLOBBER, 0, lift_reg), loop_end);
+       for (j = 0; j < mem_refs[indx_possible].num_ref; j++)
+         {
+           *(mem_refs[indx_possible].where[j]) = lift_reg;
+         }
+       emit_note_before (NOTE_INSN_LOOP_BEG, new_loop_label);
+       emit_note_before (NOTE_INSN_LOOP_END, NEXT_INSN (new_loop_jump));
+       if (loop_dump_stream)
+         {
+           fprintf (loop_dump_stream, 
+           "The following memory operand RUNTIME lifted into reg %d during loop:\n",
+           REGNO (lift_reg));
+           tdebug_rtx (SET_DEST (PATTERN (NEXT_INSN (NEXT_INSN (new_loop_jump)))),
+                       loop_dump_stream);
+           fprintf (loop_dump_stream, "\n");
+         }
+     }
+ }
+ 
+ 
+ /* 
+    Go over PAT locate all mem_refs and insert them into the mem_refs
+    structure.  WHERE is the location of PAT.  */
+ static void 
+ mark_mem_refs (pat, where)
+      rtx pat;
+      rtx *where;
+ {
+   register RTX_CODE code = GET_CODE (pat);
+   register int i, j;
+   register char *fmt;
+ 
+   switch (code)
+     {
+     case HIGH:
+     case CONST_INT:
+     case CONST:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case LABEL_REF:
+     case PC:
+     case CC0:
+       return ;
+ 
+     case SET:
+       mark_mem_refs (SET_SRC (pat), &SET_SRC (pat));
+       if (GET_CODE (SET_DEST (pat)) == MEM)
+         {
+           insert_mem_ref (SET_DEST (pat), &SET_DEST (pat), 1);
+         }
+       return;
+ 
+      case MEM:
+        insert_mem_ref (pat, where, 0);
+        return;
+ 
+     }
+ 
+   fmt = GET_RTX_FORMAT (code);
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     if (fmt[i] == 'e')
+       {
+         if( XEXP (pat, i))
+           mark_mem_refs (XEXP (pat, i), &XEXP (pat, i));
+       }
+     else if (fmt[i] == 'E' || fmt[i] == 'V')
+       {
+ 	for (j = 0; j < XVECLEN (pat, i); j++)
+ 	  mark_mem_refs (XVECEXP (pat, i, j), &XVECEXP (pat, i, j));
+       }
+ }
+ 
+ 
+ /*
+    Insert the memory reference MEM into the mem_refs structure.  
+    WHERE is location of MEM.  
+    if IS_STORE is 1 then MEM is being stored into.  */
+    
+ static void
+ insert_mem_ref (mem, where, is_store)
+   rtx mem, *where;
+   int is_store;
+ {
+   int i, j, indx, found, base_regno, index_regno;
+   rtx mem_addr, base_reg, index_reg;
+ 
+   if (num_mem_refs >= MAX_MEM_REFS)
+     {
+       return;
+     }
+   /* Find where in table to put mem.  */
+   i = 0;
+   found = 0;
+   while (i < num_mem_refs && !found)
+     {
+       if (rtx_equal_p (mem, *(mem_refs[i].where[0])))
+         {
+           found = 1;
+         }
+       else
+         {
+           i++;
+         }
+     }
+   if (!found)
+     {
+       num_mem_refs++;
+     }
+   if (i >= MAX_MEM_REFS)
+     {
+       return;
+     }
+ 
+   indx = i;
+   j = mem_refs[indx].num_ref;
+   if (j >= MAX_WHERE)
+     {
+       mem_refs[indx].varying = 1;
+       return;
+     }
+   mem_refs[indx].where[j] = where;
+   mem_refs[indx].num_ref++;
+   if (is_store)
+     {
+       mem_refs[indx].stored = 1;
+       if (j == 0)
+         {
+           mem_refs[indx].first_stored = 1;
+         }
+     }
+   if (found == 1)
+     {
+       return;
+     }
+   mem_refs[indx].varying = rtx_addr_varies_p (mem);
+   /* Now analyze the mem to find it's base and index registers if any */
+   mem_refs[indx].base_regno = NO_REG;
+   mem_refs[indx].index_regno = NO_REG;
+   index_reg = NULL;
+   base_regno = NO_REG;
+   index_regno = NO_REG;
+   base_reg = NULL;
+   mem_addr = XEXP (mem, 0);
+   if (GET_CODE (mem_addr) == SYMBOL_REF)
+     {
+       return;
+     }
+   if (GET_CODE (mem_addr) == REG)
+     {
+       base_regno = REGNO (mem_addr);
+       base_reg = (mem_addr);
+     }
+   if (GET_CODE (mem_addr) == PLUS)
+     {
+       if (GET_CODE (XEXP (mem_addr, 0)) == REG)
+ 	{
+ 	  base_regno = REGNO (XEXP (mem_addr, 0));
+ 	  base_reg = (XEXP (mem_addr, 0));
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
+ 	    {
+ 	      index_regno = REGNO (XEXP (mem_addr, 1));
+ 	      index_reg = (XEXP (mem_addr, 1));
+ 	    }
+ 	  else if (GET_CODE (XEXP (mem_addr, 1)) != CONST_INT 
+ 	           && GET_CODE (XEXP (mem_addr, 1)) != CONST
+ 	           && GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF)
+ 	    {
+ 	      index_regno = UNKNOWN;
+ 	    }
+ 	}
+       else if (GET_CODE (XEXP (mem_addr, 0)) == MULT)
+ 	{
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) == REG)
+ 	    {
+ 	      base_regno = REGNO (XEXP (mem_addr, 1));
+ 	      base_reg =  (XEXP (mem_addr, 1));
+ 	    }
+ 	  else if (GET_CODE (XEXP (mem_addr, 1)) != CONST_INT 
+ 	           && GET_CODE (XEXP (mem_addr, 1)) != CONST
+ 	           && GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF)
+ 	    {
+ 	      base_regno = UNKNOWN;
+ 	    }
+ 	  if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG
+ 	      && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == CONST_INT)
+ 	   {
+ 	     index_regno = REGNO (XEXP (XEXP (mem_addr, 0), 0));
+ 	     index_reg = (XEXP (XEXP (mem_addr, 0), 0));
+ 	   }
+ 	 else
+ 	   {
+ 	     index_regno = UNKNOWN;
+ 	   }
+ 	}
+       else if (GET_CODE (XEXP (mem_addr, 0)) == PLUS)
+ 	{
+           if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == REG)
+ 	    {
+ 	      base_regno = REGNO (XEXP (XEXP (mem_addr, 0), 0));
+ 	      base_reg = (XEXP (XEXP (mem_addr, 0), 0));
+ 	      if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG)
+ 	        {
+ 	          index_regno = REGNO (XEXP (XEXP (mem_addr, 0), 1));
+ 	          index_reg = (XEXP (XEXP (mem_addr, 0), 1));
+ 	        }
+       	      else if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != CONST_INT 
+ 	               && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != CONST
+ 	               && GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) != SYMBOL_REF)
+ 	        {
+ 	          index_regno = UNKNOWN;
+ 	        }
+ 	    }
+           else if (GET_CODE (XEXP (XEXP (mem_addr, 0), 0)) == MULT)
+ 	    {
+ 	      if (GET_CODE (XEXP (XEXP (mem_addr, 0), 1)) == REG)
+ 	        {
+ 	          base_regno = REGNO (XEXP (XEXP (mem_addr, 0), 1));
+ 	          base_reg = (XEXP (XEXP (mem_addr, 0), 1));
+ 	        }
+ 	      if (GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0)) == REG
+ 	          && GET_CODE (XEXP (XEXP (XEXP (mem_addr, 0), 0), 1)) == CONST_INT)
+ 	       {
+ 	         index_regno = REGNO (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0));
+ 	         index_reg = (XEXP (XEXP (XEXP (mem_addr, 0), 0), 0));
+ 	       }
+ 	     else
+ 	       {
+ 	         index_regno = UNKNOWN;
+ 	       }
+ 	    }
+ 	  if (GET_CODE (XEXP (mem_addr, 1)) != SYMBOL_REF
+ 	      && GET_CODE (XEXP (mem_addr, 1)) != CONST
+ 	      && GET_CODE (XEXP (mem_addr, 1)) != CONST_INT)
+ 	    {
+ 	      index_regno = UNKNOWN;
+ 	      base_regno = UNKNOWN;
+ 	    }
+ 	}
+     }
+   else if (GET_CODE (mem_addr) == MULT)
+     {
+       if (GET_CODE (XEXP (mem_addr, 0)) == REG 
+           && GET_CODE (XEXP (mem_addr, 1)) == CONST_INT)
+         {
+           index_regno = REGNO (XEXP (mem_addr, 0));
+           index_reg = (XEXP (mem_addr, 0));
+         }
+       else
+         {
+           index_regno = UNKNOWN;
+         }
+     }
+   mem_refs[indx].base_reg = base_reg;
+   mem_refs[indx].base_regno = base_regno;
+   mem_refs[indx].index_reg = index_reg;
+   mem_refs[indx].index_regno = index_regno;
+   if (base_regno == UNKNOWN || index_regno == UNKNOWN)
+     {
+       mem_refs[indx].varying = 1;
+       return;
+     }
+   if (base_regno >= max_regs_before_lift || index_regno >= max_regs_before_lift)
+     {
+       mem_refs[indx].varying = 1;
+       return;
+     }
+   if ( (base_regno == NO_REG || n_times_set[base_regno] == 0)
+       && (index_regno == NO_REG || n_times_set[index_regno] == 0))
+     {
+       mem_refs[indx].varying = 0;
+     }
+   if (MEM_VOLATILE_P (mem))
+     {
+       mem_refs[indx].varying = 1;
+     }
+ }
+  
+ 
+ static void opt_reg_use_copy (f)
+   rtx f;
+ {
+   rtx insn, src, prev;
+   int i, length;
+   char * fmt;
+   for (insn = f; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN)
+         {
+   	  if (GET_CODE (PATTERN (insn)) == SET
+ 	      && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ 	      && GET_CODE (SET_SRC (PATTERN (insn))) == REG
+ 	      && (prev = PREV_INSN (insn))
+ 	      && GET_CODE (prev) == INSN
+ 	      && GET_CODE (PATTERN (prev)) == SET
+ 	      && rtx_equal_p (SET_SRC (PATTERN (insn)), 
+ 	                      SET_DEST (PATTERN (prev))))
+ 	    {
+               src = SET_SRC (PATTERN (prev));
+               fmt = GET_RTX_FORMAT (GET_CODE (src));
+               length = GET_RTX_LENGTH (GET_CODE (src));
+               for (i=0; i<length; i++)
+                 {
+                   if (fmt[i] == 'e' 
+                       && GET_CODE (XEXP (src, i)) == REG
+                       && rtx_equal_p (XEXP (src, i), SET_DEST (PATTERN (insn))))
+                     {  
+                       SET_DEST (PATTERN (insn)) = SET_SRC (PATTERN (insn));
+                       SET_SRC (PATTERN (insn)) = XEXP (src, i);
+                       SET_DEST (PATTERN (prev)) = XEXP (src, i);
+                       emit_insn_after (gen_rtx (USE, 0, 
+                                                 SET_DEST (PATTERN (prev))),
+                                        prev);
+                       break;
+                     }
+                 }
+ 	    }
+ 	}
+     }
  }
diff -rNci gcc-2.7.2/loop.h gcc-2.7.2p/loop.h
*** gcc-2.7.2/loop.h	Fri Jul 14 12:23:28 1995
--- gcc-2.7.2p/loop.h	Tue Jan 23 09:25:29 1996
***************
*** 88,93 ****
--- 88,97 ----
    unsigned maybe_dead : 1;	/* 1 if this giv might be dead.  In that case,
  				   we won't use it to eliminate a biv, it
  				   would probably lose. */
+ #ifdef REDUCE_INDEX
+   unsigned is_index_induc:1; /* 1 if this is actually the index portion
+                                 of a DEST_ADDR g_type intel1 */
+ #endif
    int lifetime;			/* Length of life of this giv */
    int times_used;		/* # times this giv is used. */
    rtx derive_adjustment;	/* If nonzero, is an adjustment to be
***************
*** 133,138 ****
--- 137,144 ----
    unsigned nonneg : 1;		/* 1 if we added a REG_NONNEG note for this. */
    unsigned reversed : 1;	/* 1 if we reversed the loop that this
  				   biv controls. */
+   unsigned retry_celim :2; /*intel1 is >0 if we should retry compare 
+                              elimination at the end of strength reduction */
  };
  
  /* Definitions used by the basic induction variable discovery code.  */
***************
*** 146,152 ****
  extern int *uid_loop_num;
  extern int *loop_outer_loop;
  extern rtx *loop_number_exit_labels;
- extern int *loop_number_exit_count;
  extern unsigned HOST_WIDE_INT loop_n_iterations;
  extern int max_reg_before_loop;
  
--- 152,157 ----
diff -rNci gcc-2.7.2/obstack.c gcc-2.7.2p/obstack.c
*** gcc-2.7.2/obstack.c	Sun Nov 26 19:57:12 1995
--- gcc-2.7.2p/obstack.c	Thu Jun 15 22:12:08 1995
***************
*** 17,46 ****
  
  #include "obstack.h"
  
! /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
!    incremented whenever callers compiled using an old obstack.h can no
!    longer properly call the functions in this obstack.c.  */
! #define OBSTACK_INTERFACE_VERSION 1
  
  /* Comment out all this code if we are using the GNU C Library, and are not
!    actually compiling the library itself, and the installed library
!    supports the same library interface we do.  This code is part of the GNU
!    C Library, but also included in many other GNU distributions.  Compiling
     and linking in this code is a waste when using the GNU C library
     (especially if it is a shared library).  Rather than having every GNU
!    program understand `configure --with-gnu-libc' and omit the object
!    files, it is simpler to just do this in the source for each such file.  */
  
! #include <stdio.h>		/* Random thing to get __GNU_LIBRARY__.  */
! #if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
! #include <gnu-versions.h>
! #if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
! #define ELIDE_CODE
! #endif
! #endif
! 
! 
! #ifndef ELIDE_CODE
  
  
  #if defined (__STDC__) && __STDC__
--- 17,34 ----
  
  #include "obstack.h"
  
! /* This is just to get __GNU_LIBRARY__ defined.  */
! #include <stdio.h>
  
  /* Comment out all this code if we are using the GNU C Library, and are not
!    actually compiling the library itself.  This code is part of the GNU C
!    Library, but also included in many other GNU distributions.  Compiling
     and linking in this code is a waste when using the GNU C library
     (especially if it is a shared library).  Rather than having every GNU
!    program understand `configure --with-gnu-libc' and omit the object files,
!    it is simpler to just do this in the source for each such file.  */
  
! #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  
  
  #if defined (__STDC__) && __STDC__
***************
*** 494,497 ****
  
  #endif /* 0 */
  
! #endif	/* !ELIDE_CODE */
--- 482,485 ----
  
  #endif /* 0 */
  
! #endif	/* _LIBC or not __GNU_LIBRARY__.  */
diff -rNci gcc-2.7.2/optabs.c gcc-2.7.2p/optabs.c
*** gcc-2.7.2/optabs.c	Sat Oct 21 22:16:13 1995
--- gcc-2.7.2p/optabs.c	Thu Jun 15 11:55:15 1995
***************
*** 3511,3517 ****
  	      /* The sign bit is not set.  Convert as signed.  */
  	      expand_float (target, from, 0);
  	      emit_jump_insn (gen_jump (label));
- 	      emit_barrier ();
  
  	      /* The sign bit is set.
  		 Convert to a usable (positive signed) value by shifting right
--- 3511,3516 ----
diff -rNci gcc-2.7.2/output.h gcc-2.7.2p/output.h
*** gcc-2.7.2/output.h	Fri Jul 14 12:02:05 1995
--- gcc-2.7.2p/output.h	Thu Jun 15 11:55:44 1995
***************
*** 376,386 ****
  
  extern int current_function_varargs;
  
- /* Nonzero if current function uses stdarg.h or equivalent.
-    Zero for functions that use varargs.h.  */
- 
- extern int current_function_stdarg;
- 
  /* Quantities of various kinds of registers
     used for the current function's args.  */
  
--- 376,381 ----
diff -rNci gcc-2.7.2/print-rtl.c gcc-2.7.2p/print-rtl.c
*** gcc-2.7.2/print-rtl.c	Thu Jun 15 11:56:24 1995
--- gcc-2.7.2p/print-rtl.c	Tue Jan 23 09:25:29 1996
***************
*** 231,236 ****
--- 231,246 ----
    fprintf (stderr, "\n");
  }
  
+ void
+ tdebug_rtx(x, file)
+ 	rtx x;
+ 	FILE *file;
+ {
+   outfile=file;
+   print_rtx(x);
+   fprintf(file, "\n");
+ }
+ 
  /* Count of rtx's to print with debug_rtx_list.
     This global exists because gdb user defined commands have no arguments.  */
  
diff -rNci gcc-2.7.2/real.c gcc-2.7.2p/real.c
*** gcc-2.7.2/real.c	Tue Aug 15 21:57:18 1995
--- gcc-2.7.2p/real.c	Thu Jun 15 11:57:39 1995
***************
*** 2635,2647 ****
       unsigned EMUSHORT *a, *b, *c;
  {
    unsigned EMUSHORT ai[NI], bi[NI];
!   int i, sign;
    EMULONG lt, lta, ltb;
  
- /* IEEE says if result is not a NaN, the sign is "-" if and only if
-    operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
-   sign = eisneg(a) ^ eisneg(b);
- 
  #ifdef NANS
  /* Return any NaN input. */
    if (eisnan (a))
--- 2635,2643 ----
       unsigned EMUSHORT *a, *b, *c;
  {
    unsigned EMUSHORT ai[NI], bi[NI];
!   int i;
    EMULONG lt, lta, ltb;
  
  #ifdef NANS
  /* Return any NaN input. */
    if (eisnan (a))
***************
*** 2659,2665 ****
        || (eisinf (a) && eisinf (b)))
      {
      mtherr ("ediv", INVALID);
!     enan (c, sign);
      return;
      }
  #endif
--- 2655,2661 ----
        || (eisinf (a) && eisinf (b)))
      {
      mtherr ("ediv", INVALID);
!     enan (c, eisneg (a) ^ eisneg (b));
      return;
      }
  #endif
***************
*** 2667,2680 ****
  #ifdef INFINITY
    if (eisinf (b))
      {
        einfin (c);
!       goto divsign;
      }
  /* Anything else over infinity is zero. */
    if (eisinf (a))
      {
        eclear (c);
!       goto divsign;
      }
  #endif
    emovi (a, ai);
--- 2663,2680 ----
  #ifdef INFINITY
    if (eisinf (b))
      {
+       if (eisneg (a) ^ eisneg (b))
+ 	*(c + (NE - 1)) = 0x8000;
+       else
+ 	*(c + (NE - 1)) = 0;
        einfin (c);
!       return;
      }
  /* Anything else over infinity is zero. */
    if (eisinf (a))
      {
        eclear (c);
!       return;
      }
  #endif
    emovi (a, ai);
***************
*** 2692,2698 ****
  	    }
  	}
        eclear (c);
!       goto divsign;
      }
   dnzro1:
  
--- 2692,2698 ----
  	    }
  	}
        eclear (c);
!       return;
      }
   dnzro1:
  
***************
*** 2706,2716 ****
  	      goto dnzro2;
  	    }
  	}
  /* Divide by zero is not an invalid operation.
     It is a divide-by-zero operation!   */
        einfin (c);
        mtherr ("ediv", SING);
!       goto divsign;
      }
   dnzro2:
  
--- 2706,2720 ----
  	      goto dnzro2;
  	    }
  	}
+       if (ai[0] == bi[0])
+ 	*(c + (NE - 1)) = 0;
+       else
+ 	*(c + (NE - 1)) = 0x8000;
  /* Divide by zero is not an invalid operation.
     It is a divide-by-zero operation!   */
        einfin (c);
        mtherr ("ediv", SING);
!       return;
      }
   dnzro2:
  
***************
*** 2718,2735 ****
    /* calculate exponent */
    lt = ltb - lta + EXONE;
    emdnorm (bi, i, 0, lt, 64);
!   emovo (bi, c);
! 
!  divsign:
! 
!   if (sign
! #ifndef IEEE
!       && (ecmp (c, ezero) != 0)
! #endif
!       )
!      *(c+(NE-1)) |= 0x8000;
    else
!      *(c+(NE-1)) &= ~0x8000;
  }
  
  /* Multiply e-types A and B, return e-type product C.   */
--- 2722,2733 ----
    /* calculate exponent */
    lt = ltb - lta + EXONE;
    emdnorm (bi, i, 0, lt, 64);
!   /* set the sign */
!   if (ai[0] == bi[0])
!     bi[0] = 0;
    else
!     bi[0] = 0Xffff;
!   emovo (bi, c);
  }
  
  /* Multiply e-types A and B, return e-type product C.   */
***************
*** 2739,2751 ****
       unsigned EMUSHORT *a, *b, *c;
  {
    unsigned EMUSHORT ai[NI], bi[NI];
!   int i, j, sign;
    EMULONG lt, lta, ltb;
  
- /* IEEE says if result is not a NaN, the sign is "-" if and only if
-    operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
-   sign = eisneg(a) ^ eisneg(b);
- 
  #ifdef NANS
  /* NaN times anything is the same NaN. */
    if (eisnan (a))
--- 2737,2745 ----
       unsigned EMUSHORT *a, *b, *c;
  {
    unsigned EMUSHORT ai[NI], bi[NI];
!   int i, j;
    EMULONG lt, lta, ltb;
  
  #ifdef NANS
  /* NaN times anything is the same NaN. */
    if (eisnan (a))
***************
*** 2763,2769 ****
        || (eisinf (b) && (ecmp (a, ezero) == 0)))
      {
      mtherr ("emul", INVALID);
!     enan (c, sign);
      return;
      }
  #endif
--- 2757,2763 ----
        || (eisinf (b) && (ecmp (a, ezero) == 0)))
      {
      mtherr ("emul", INVALID);
!     enan (c, eisneg (a) ^ eisneg (b));
      return;
      }
  #endif
***************
*** 2771,2778 ****
  #ifdef INFINITY
    if (eisinf (a) || eisinf (b))
      {
        einfin (c);
!       goto mulsign;
      }
  #endif
    emovi (a, ai);
--- 2765,2776 ----
  #ifdef INFINITY
    if (eisinf (a) || eisinf (b))
      {
+       if (eisneg (a) ^ eisneg (b))
+ 	*(c + (NE - 1)) = 0x8000;
+       else
+ 	*(c + (NE - 1)) = 0;
        einfin (c);
!       return;
      }
  #endif
    emovi (a, ai);
***************
*** 2790,2796 ****
  	    }
  	}
        eclear (c);
!       goto mulsign;
      }
   mnzer1:
  
--- 2788,2794 ----
  	    }
  	}
        eclear (c);
!       return;
      }
   mnzer1:
  
***************
*** 2805,2811 ****
  	    }
  	}
        eclear (c);
!       goto mulsign;
      }
   mnzer2:
  
--- 2803,2809 ----
  	    }
  	}
        eclear (c);
!       return;
      }
   mnzer2:
  
***************
*** 2814,2831 ****
    /* calculate exponent */
    lt = lta + ltb - (EXONE - 1);
    emdnorm (bi, j, 0, lt, 64);
!   emovo (bi, c);
! 
!  mulsign:
! 
!   if (sign
! #ifndef IEEE
!       && (ecmp (c, ezero) != 0)
! #endif
!       )
!      *(c+(NE-1)) |= 0x8000;
    else
!      *(c+(NE-1)) &= ~0x8000;
  }
  
  /* Convert double precision PE to e-type Y.  */
--- 2812,2823 ----
    /* calculate exponent */
    lt = lta + ltb - (EXONE - 1);
    emdnorm (bi, j, 0, lt, 64);
!   /* calculate sign of product */
!   if (ai[0] == bi[0])
!     bi[0] = 0;
    else
!     bi[0] = 0xffff;
!   emovo (bi, c);
  }
  
  /* Convert double precision PE to e-type Y.  */
diff -rNci gcc-2.7.2/recog.c gcc-2.7.2p/recog.c
*** gcc-2.7.2/recog.c	Sat Jul  1 10:52:35 1995
--- gcc-2.7.2p/recog.c	Thu Jun 15 11:58:34 1995
***************
*** 864,880 ****
  	 reg went on the stack.)  */
        if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM)
  	return general_operand (op, mode);
- 
- #ifdef CLASS_CANNOT_CHANGE_SIZE
-       if (GET_CODE (SUBREG_REG (op)) == REG
- 	  && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER
- 	  && TEST_HARD_REG_BIT (reg_class_contents[(int) CLASS_CANNOT_CHANGE_SIZE],
- 				REGNO (SUBREG_REG (op)))
- 	  && (GET_MODE_SIZE (mode)
- 	      != GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
- 	return 0;
- #endif
- 
        op = SUBREG_REG (op);
      }
  
--- 864,869 ----
diff -rNci gcc-2.7.2/reg-stack.c gcc-2.7.2p/reg-stack.c
*** gcc-2.7.2/reg-stack.c	Thu Jun 15 21:36:05 1995
--- gcc-2.7.2p/reg-stack.c	Tue Jan 23 09:25:29 1996
***************
*** 230,235 ****
--- 230,238 ----
    ((INSN_UID (INSN) > max_uid)	\
     ? (abort() , -1) : block_number[INSN_UID (INSN)])
  
+ /* intel1 */
+ extern FILE *stack_reg_dump_file;
+ 
  extern rtx forced_labels;
  extern rtx gen_jump ();
  extern rtx gen_movdf (), gen_movxf ();
***************
*** 2121,2126 ****
--- 2124,2131 ----
  	replace_reg (dest, FIRST_STACK_REG);
  	break;
  
+       /* intel1 */
+       case FLOAT_EXTEND:
        case REG:
  	/* This is a `tstM2' case. */
  	if (*dest != cc0_rtx)
***************
*** 3131,3134 ****
--- 3136,5348 ----
        fprintf (file, "\n");
      }
  }
+ /* intel1 */
+ #ifdef IS_STACK_MODE
+ #include "basic-block.h"
+ #include "obstack.h"
+ #define obstack_chunk_alloc xmalloc
+ #define obstack_chunk_free free
+ 
+ extern int regset_bytes;
+ extern struct obstack momentary_obstack;
+ extern rtx *regno_reg_rtx;
+ extern int max_regno;
+ 
+ static void func_stack_reg_to_stack_slot ();
+ static void bb_stack_reg_to_stack_slot ();
+ void float_to_int_cmp ();
+ static void offload_if_necessary ();
+ static void offload_reg ();
+ static void replace_with_stack_slot ();
+ static int stack_reg_dies_at_store ();
+ static void mark_stack_regs_mentioned ();
+ static void replace_with_temp_slot ();
+ static int reg_dead_at_pred ();
+ static int reg_only_set_or_stored ();
+ static int reg_used_in_body ();
+ static int store_into_temp ();
+ static int visit_till_dies ();
+ static int addr_or_val_changed ();
+ static void find_regs_mentioned ();
+ static int tests_equality ();
+ static int reg_last_loaded ();
+ static int reg_def_in_unvisited ();
+ static rtx reg_dies_in_block ();
+ static int death_blocks_ok ();
+ 
+ /* For each basic block the union of the basic_block_live_at_start
+    of each of it's successors.  */
+ regset *basic_block_maybe_live_at_end;
+ 
+ /* To mark each block visited on a path */
+ char *blocks_visited;
+ 
+ /* To mark those blocks on the path where the reg dies.
+    It is set to the NEXT_INSN of the insn in the block where
+    the reg dies */
+ rtx *death_blocks;
+ 
+ /* To mark those blocks where the reg is defined */
+ char *blocks_defined;
+ 
+ /* For finding block sucessors */
+ int *fall_thru_block, *jump_target_block;
+ 
+ /* The temp slots allocated to stack regs */
+ rtx *reg_temp_slot;
+ 
+ int num_visits;
+ 
+ /* Information collected for optimizing use of stack regs
+    within a basic block
+ */
+ struct stack_reg_infos
+   {
+     rtx store_insn;
+     rtx non_dead_store[3];
+     rtx last_use;
+     unsigned char num_non_dead_store;
+     unsigned char dies_at_store;
+   }
+ 
+  *stack_reg_info;
+ 
+ static
+ struct regs_mentioned
+   {
+     rtx reg;
+     struct regs_mentioned *next;
+   } *reg_mentioned_header;
+ 
+ void init_regset_vector ();
+ 
+ void
+ opt_reg_stack ()
+ {
+ 
+   reg_temp_slot = (rtx *) alloca (max_regno * sizeof (rtx));
+   bzero (reg_temp_slot, max_regno * sizeof (rtx));
+ 
+   if (stack_reg_dump_file)
+     {
+       fprintf (stack_reg_dump_file," MAX_REGNO at start %d\n",max_regno);
+     }
+   func_stack_reg_to_stack_slot ();
+   bb_stack_reg_to_stack_slot ();
+ #ifdef SPARE_REGS
+   max_regno = max_reg_num();
+   if (stack_reg_dump_file)
+     {
+       fprintf (stack_reg_dump_file," MAX_REGNO at end %d\n",max_regno);
+     }
+ #endif
+ }
+ 
+ /*
+    Stack mode registers that are used only to move values
+    in a basic block are replaced with stack slots.
+    We also have something like this for between basic blocks
+    see the ear spec agc()/earfilters.c the last loop
+ */
+ static void
+ bb_stack_reg_to_stack_slot ()
+ {
+   int block, nregs, stack_regno, num_calls;
+   rtx insn;
+ 
+   nregs = max_regno;
+   stack_reg_info = (struct stack_reg_infos *)
+     alloca (nregs * sizeof (struct stack_reg_infos));
+ 
+   for (block = 0; block < n_basic_blocks; block++)
+     {
+       bzero (stack_reg_info, nregs * sizeof (struct stack_reg_infos));
+       num_calls = 0;
+       for (insn = basic_block_end[block];
+ 	   insn && insn != PREV_INSN (basic_block_head[block]);
+ 	   insn = PREV_INSN (insn))
+ 	{
+ 	  if (GET_CODE (insn) == CALL_INSN)
+ 	    num_calls++;
+ 	  if (GET_CODE (insn) == INSN)
+ 	    {
+ 	      if (GET_CODE (PATTERN (insn)) != SET)
+ 		{
+ 		  if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 		    {
+ 		      if (flag_do_offload)
+ 			offload_if_necessary (insn, block);
+ 		    }
+ 		  bzero (stack_reg_info, nregs * sizeof (struct stack_reg_infos));
+ 		}
+ 	      else
+ 		{
+ 		  if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ 		      && GET_MODE (SET_DEST (PATTERN (insn))) == SFmode
+ 		      && GET_CODE (SET_SRC (PATTERN (insn))) == FLOAT_TRUNCATE)
+ 		    {
+ 		      rtx slot;
+ 		      slot 
+ 		        = assign_stack_local (SFmode, GET_MODE_SIZE (SFmode), -1);
+ 		      emit_insn_after (gen_rtx (SET, 0, SET_DEST (PATTERN (insn)),
+ 		                                slot), insn);
+ 		      SET_DEST (PATTERN (insn)) = slot;
+ 		    }
+ 		  stack_regno = -1;
+ 		  if (stack_reg_dies_at_store (insn, &stack_regno))
+ 		    { /* A store of stack_regno at which it dies.  */
+ 		      stack_reg_info[stack_regno].dies_at_store = 1;
+ 		      stack_reg_info[stack_regno].store_insn = insn;
+ 		      stack_reg_info[stack_regno].num_non_dead_store = 0;
+ 		    }
+ 		  else if (stack_regno != -1)
+ 		    {
+ 		      /* Stored but not dead.  */
+ 		      stack_reg_info[stack_regno].num_non_dead_store++;
+ 		      if (stack_reg_info[stack_regno].num_non_dead_store <= 3)
+ 			{
+ 			  stack_reg_info[stack_regno].non_dead_store
+ 			    [stack_reg_info[stack_regno].num_non_dead_store - 1] 
+ 			    = insn;
+ 			}
+ 		      else
+ 			{
+ 			  stack_reg_info[stack_regno].dies_at_store = 0;
+ 			  stack_reg_info[stack_regno].store_insn = NULL;
+ 			  stack_reg_info[stack_regno].last_use = NULL;
+ 			  stack_reg_info[stack_regno].num_non_dead_store = 0;
+ 			}
+ 		    }
+ 		  else
+ 		    mark_stack_regs_mentioned (SET_SRC (PATTERN (insn)), insn);
+ 		  if (GET_CODE (SET_DEST (PATTERN (insn))) != REG)
+ 		    mark_stack_regs_mentioned (SET_DEST (PATTERN (insn)), insn);
+ 		  if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ 		      && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (insn))))
+ 		    )
+ 		    { /* A setting of a stack register.  */
+ 		      if (((GET_CODE (SET_SRC (PATTERN (insn))) == MEM
+ 			     && !MEM_VOLATILE_P (SET_SRC (PATTERN (insn))))
+ 			   || GET_CODE (SET_SRC (PATTERN (insn))) == CONST_DOUBLE)
+ 			  && stack_reg_info[REGNO (SET_DEST (PATTERN (insn)))].dies_at_store)
+ 			{ /* It is loaded from a non volatile memory and
+ 			     was stored upon death later in the basic block,
+ 			     try to do this NOT via the register stack.  */
+ 			  replace_with_stack_slot (insn, block, num_calls);
+ 			}
+ 		      else
+ 			{ /* Just try to optimize consecutive stores and
+ 			     restart the information gathering.  
+ 			  */
+ 			  stack_regno = REGNO (SET_DEST (PATTERN (insn)));
+ 			  opt_consec_stores (stack_regno);
+ 			  stack_reg_info[stack_regno].dies_at_store = 0;
+ 			  stack_reg_info[stack_regno].store_insn = NULL;
+ 			  stack_reg_info[stack_regno].last_use = NULL;
+ 			  stack_reg_info[stack_regno].num_non_dead_store = 0;
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ /*
+     Change
+             fst   mem1
+             fstp  mem2
+     to
+            fstp  mem1
+            mov   mem1,mem2
+     regno is the number of the stack register being stored.  
+ */
+ opt_consec_stores (regno)
+      int regno;
+ {
+   rtx insn, note;
+ 
+   if (stack_reg_info[regno].store_insn
+       && stack_reg_info[regno].dies_at_store
+       && stack_reg_info[regno].num_non_dead_store != 0
+       && stack_reg_info[regno].non_dead_store[0] ==
+       PREV_INSN (stack_reg_info[regno].store_insn))
+     {
+       insn = stack_reg_info[regno].store_insn;
+       SET_SRC (PATTERN (insn)) 
+ 	= copy_rtx (SET_DEST (PATTERN (stack_reg_info[regno].non_dead_store[0])));
+       if (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == PRE_DEC
+ 	  || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == PRE_INC)
+ 	{
+ 	  XEXP (SET_SRC (PATTERN (insn)), 0) =
+ 	    XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0);
+ 	}
+       INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
+       note = find_regno_note (insn, REG_DEAD, regno);
+       remove_note (insn, note);
+       if (!find_regno_note (stack_reg_info[regno].non_dead_store[0], REG_DEAD, regno))
+ 	{
+ 	  REG_NOTES (stack_reg_info[regno].non_dead_store[0])
+ 	    = gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
+ 		       REG_NOTES (stack_reg_info[regno].non_dead_store[0]));
+ 	}
+     }
+ }
+ 
+ 
+ /*
+   If the register being compared is the result of a computation in
+   this block, and the second comparison operand is not so, and it is
+   being compared for equality.  
+     offload and reload it before the compare
+   The reason for this is that the stack registers are 80bit precision
+   and hence the comparison may fail due to precision.  
+ */
+ 
+ static void
+ offload_if_necessary (insn, blocknum)
+      rtx insn;
+      int blocknum;
+ {
+   rtx cmp_part, new_insn, last_set_insn, assign_stack_local ();
+   int regno;
+ 
+   if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
+     {
+       cmp_part = XVECEXP (PATTERN (insn), 0, 0);
+       last_set_insn = NULL;
+       if (SET_DEST (cmp_part) == cc0_rtx
+ 	  && GET_CODE (SET_SRC (cmp_part)) == COMPARE
+ 	  && GET_MODE (SET_SRC (cmp_part)) == CCmode)
+ 	{
+ 	  if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
+ 	      && GET_MODE (XEXP (SET_SRC (cmp_part), 0)) == DFmode
+ 	      && GET_CODE (XEXP (SET_SRC (cmp_part), 1)) != REG
+ 	      && !reg_last_loaded (blocknum, PREV_INSN (insn),
+ 		       REGNO (XEXP (SET_SRC (cmp_part), 0)), &last_set_insn)
+ 	      && last_set_insn
+ 	      && tests_equality (NEXT_INSN (insn)))
+ 	    {
+ 	      regno = REGNO (XEXP (SET_SRC (cmp_part), 0));
+ 	      if (reg_temp_slot[regno] == NULL)
+ 		{
+ 		  reg_temp_slot[regno] 
+ 		    = assign_stack_local (GET_MODE (XEXP (SET_SRC (cmp_part), 0)),
+ 		    GET_MODE_SIZE (GET_MODE (XEXP (SET_SRC (cmp_part), 0))),
+ 					-1);
+ 		}
+ 	      MEM_VOLATILE_P (reg_temp_slot[regno]) = 1;
+ 	      new_insn 
+ 		= emit_insn_before (
+ 				   gen_rtx (SET, 0,
+ 			reg_temp_slot[regno], XEXP (SET_SRC (cmp_part), 0)),
+ 				   insn);
+ 	      if (basic_block_head[blocknum] == insn)
+ 		{
+ 		  basic_block_head[blocknum] = new_insn;
+ 		}
+ 	      REG_NOTES (new_insn) 
+ 		= gen_rtx (EXPR_LIST, REG_DEAD,
+ 			 XEXP (SET_SRC (cmp_part), 0),
+ 			 REG_NOTES (new_insn));
+ 	      reg_n_deaths[regno]++;
+ 	      emit_insn_before (
+ 				 gen_rtx (SET, 0,
+ 			XEXP (SET_SRC (cmp_part), 0), reg_temp_slot[regno]),
+ 				 insn);
+ 	    }
+ 	}
+     }
+ }
+ 
+ 
+ /*
+   Return 1 if the insn which is a jump insn tests for equality or
+   inequality
+   else return 0
+ */
+ 
+ static int
+ tests_equality (insn)
+      rtx insn;
+ {
+   if (GET_CODE (insn) == JUMP_INSN &&
+       GET_CODE (PATTERN (insn)) == SET &&
+       SET_DEST (PATTERN (insn)) == pc_rtx &&
+       GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE &&
+       (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == NE ||
+        GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == EQ))
+     {
+       return (1);
+     }
+   return (0);
+ }
+ 
+ 
+ /*
+    Search backward in block# blocknum, beginning at insn for a set of
+    reg# regno. 
+    if found
+      set *last_set_insn to that set
+      if the source that sets regno is one of the desired sources
+      (see below) return 1
+      else return 0
+    else return 0
+ */
+ static int
+ reg_last_loaded (blocknum, insn, regno, last_set_insn)
+      int blocknum, regno;
+      rtx insn, *last_set_insn;
+ {
+   rtx last_set;
+   int found, i;
+ 
+   last_set = insn;
+   found = 0;
+   while (!found && last_set != PREV_INSN (basic_block_head[blocknum]))
+     {
+       if (GET_CODE (last_set) == INSN)
+ 	{
+ 	  if (GET_CODE (PATTERN (last_set)) == PARALLEL)
+ 	    {
+ 	      for (i = 0; i < XVECLEN (PATTERN (last_set), 0); i++)
+ 		{
+ 		  if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == SET)
+ 		    {
+ 		      if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
+ 			  REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
+ 			{
+ 			  *last_set_insn = last_set;
+ 			  return (0);
+ 			}
+ 		    }
+ 		  else if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == CLOBBER)
+ 		    {
+ 		      if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
+ 			  REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
+ 			{
+ 			  *last_set_insn = last_set;
+ 			  return (0);
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      return (0);
+ 		    }
+ 		}
+ 	    }
+ 	  if ((GET_CODE (PATTERN (last_set)) == SET ||
+ 	       GET_CODE (PATTERN (last_set)) == CLOBBER) &&
+ 	      GET_CODE (SET_DEST (PATTERN (last_set))) == REG &&
+ 	      REGNO (SET_DEST (PATTERN (last_set))) == regno)
+ 	    {
+ 	      if (GET_CODE (PATTERN (last_set)) == CLOBBER)
+ 		{
+ 		  *last_set_insn = last_set;
+ 		  return (0);
+ 		}
+ 	      if (GET_CODE (SET_SRC (PATTERN (last_set))) != MEM
+ 		  && GET_CODE (SET_SRC (PATTERN (last_set))) != CONST_DOUBLE
+ 		  && GET_CODE (SET_SRC (PATTERN (last_set))) != REG
+ 		  && GET_CODE (SET_SRC (PATTERN (last_set))) != SUBREG
+ 		  && GET_CODE (SET_SRC (PATTERN (last_set))) != FLOAT
+ 		  && GET_CODE (SET_SRC (PATTERN (last_set))) != FLOAT_EXTEND)
+ 		{
+ 		  *last_set_insn = last_set;
+ 		  return (0);
+ 		}
+ 	      else
+ 		{
+ 		  *last_set_insn = last_set;
+ 		  if (GET_CODE (SET_SRC (PATTERN (last_set))) == REG &&
+ 		      REGNO (SET_SRC (PATTERN (last_set))) < FIRST_PSEUDO_REGISTER)
+ 		    return (0);
+ 		  return (1);
+ 		}
+ 	    }
+ 	}
+       if (!found)
+ 	{
+ 	  last_set = PREV_INSN (last_set);
+ 	}
+     }
+   return (0);
+ }
+ 
+ 
+ /*
+   insn loads a stack reg from memory and later on in the block
+   at stack_reg_info[REGNO(SET_DEST(PATTERN(insn)))].store_insn
+   that stack reg is stored into memory and marked as dead.  Also
+   no insn between these two insns sets that stack reg. 
+   This procedure changes the store from the register stack to
+   a store from the regular stack - which is faster.  
+ */
+ static void
+ replace_with_stack_slot (insn, block_num, num_calls)
+      rtx insn;
+      int block_num, num_calls;
+ {
+   rtx note, stack_slot, store_insn, new_insn;
+   rtx notes_to_move, assign_stack_local ();
+   int i, regno, mem_possibly_changed;
+   char *storage;
+ 
+   notes_to_move = NULL;
+   regno = REGNO (SET_DEST (PATTERN (insn)));
+   store_insn = stack_reg_info[regno].store_insn;
+   storage = (char *) obstack_alloc (&momentary_obstack, 0);
+ 
+   /* Check if the memory being loaded into the stack register may
+      possibly change between insn and store_insn.  
+   */
+   mem_possibly_changed 
+     = (GET_CODE (SET_SRC (PATTERN (insn))) == CONST_DOUBLE) ? 0 :
+       addr_or_val_changed (SET_SRC (PATTERN (insn)), insn, store_insn);
+   obstack_free (&momentary_obstack, storage);
+   if (stack_reg_dump_file)
+     {
+       fprintf (stack_reg_dump_file,
+ 	       "Offload stack reg%d used only within basic block insn %d store_insn %d\n",
+        regno, INSN_UID (insn), INSN_UID (stack_reg_info[regno].store_insn));
+       if (stack_reg_info[regno].last_use != NULL)
+ 	{
+ 	  fprintf (stack_reg_dump_file,
+ 		   " reg used at insn %d\n",
+ 		   INSN_UID (stack_reg_info[regno].last_use));
+ 	}
+     }
+   if (reg_temp_slot[regno] == NULL && mem_possibly_changed)
+     { /* Must allocate a stack slot */
+ #ifdef SPARE_REGS
+       if (max_reg_num () < max_regno)
+         {
+           if (GET_MODE (SET_DEST (PATTERN (insn))) == SFmode)
+             reg_temp_slot[regno] = gen_reg_rtx (SImode);
+           else
+             reg_temp_slot[regno] 
+ 	      = assign_stack_local (GET_MODE (SET_DEST (PATTERN (insn))),
+ 		   GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn)))),
+ 			    -1);
+         }
+       else
+ #endif
+         reg_temp_slot[regno] 
+ 	  = assign_stack_local (GET_MODE (SET_DEST (PATTERN (insn))),
+ 		       GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn)))),
+ 			    -1);
+     }
+   if (mem_possibly_changed)
+     /* Use the stack slot */
+     stack_slot = reg_temp_slot[regno];
+   else
+     /* The memory slot from which the stack register was loaded can be used */
+     stack_slot = SET_SRC (PATTERN (insn));
+   if (stack_reg_info[regno].last_use == NULL)
+     { /* The stack register was not used between the load and store */
+       if (mem_possibly_changed)
+ 	{
+ 	  SET_DEST (PATTERN (insn)) = stack_slot;
+ 	  if (GET_CODE (stack_slot) == REG)
+ 	    {
+               if (GET_CODE (SET_SRC (PATTERN (insn)))
+                   == CONST_DOUBLE)
+                 {
+                   SET_SRC (PATTERN (insn)) = 
+                     gen_rtx (CONST_INT, 0, CONST_DOUBLE_HIGH (SET_SRC (PATTERN (insn))));
+                 }
+               else
+                 {
+ 	          PUT_MODE (SET_SRC (PATTERN (insn)), GET_MODE (stack_slot));
+ 	        }
+ 	    }
+ 	  INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
+ 	}
+       else
+ 	{
+ 	  PUT_CODE (insn, NOTE);
+ 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 	  NOTE_SOURCE_FILE (insn) = 0;
+ 	  notes_to_move = REG_NOTES (insn);
+ 	}
+     }
+   else
+     { /* The stack register was also used in some computation */
+       if (mem_possibly_changed)
+ 	{
+ 	  new_insn 
+ 	    = emit_insn_after (
+ 	  gen_rtx (SET, 0, stack_slot, copy_rtx (SET_SRC (PATTERN (insn)))),
+ 			      insn);
+ 	  if (GET_CODE (stack_slot) == REG)
+ 	    {
+ 	      PUT_MODE (SET_SRC (PATTERN (new_insn)), GET_MODE (stack_slot));
+ 	    }
+ 	  INSN_CODE (new_insn) = recog (PATTERN (new_insn), new_insn, 0);
+ 	}
+     }
+   SET_SRC (PATTERN (store_insn)) = stack_slot;
+   if (GET_CODE (stack_slot) == REG )
+     {
+       reg_n_refs[REGNO (stack_slot)]++;
+       reg_n_sets[REGNO (stack_slot)]++;
+       reg_n_calls_crossed[REGNO (stack_slot)] = num_calls;
+       reg_n_deaths[REGNO (stack_slot)]++;
+       if (reg_basic_block[REGNO (stack_slot)] != -1)
+         {
+           reg_basic_block[REGNO (stack_slot)] = REG_BLOCK_GLOBAL;
+         }
+       else
+         {
+           reg_basic_block[REGNO (stack_slot)] = block_num;
+         }
+       PUT_MODE (SET_DEST (PATTERN (store_insn)), GET_MODE (stack_slot));
+       REG_NOTES (store_insn) = 
+         gen_rtx (EXPR_LIST, REG_DEAD, stack_slot, REG_NOTES (store_insn));
+     }
+   INSN_CODE (store_insn) = recog (PATTERN (store_insn), store_insn, 0);
+   note = find_regno_note (store_insn, REG_DEAD, regno);
+   remove_note (store_insn, note);
+   if (notes_to_move)
+     { /* Maintain consistency of REG NOTE information */
+       rtx link, prev_link;
+       prev_link = REG_NOTES (store_insn);
+       for (link = REG_NOTES (store_insn); link; link = XEXP (link, 1))
+ 	{
+ 	  prev_link = link;
+ 	}
+       if (prev_link)
+ 	{
+ 	  XEXP (prev_link, 1) = notes_to_move;
+ 	}
+       else
+ 	{
+ 	  REG_NOTES (store_insn) = notes_to_move;
+ 	}
+     }
+   if (stack_reg_info[regno].last_use == NULL)
+     {
+       reg_n_deaths[regno]--;
+     }
+   else if (!find_regno_note (stack_reg_info[regno].last_use, REG_DEAD, regno))
+     {
+       REG_NOTES (stack_reg_info[regno].last_use)
+ 	= gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
+ 		   REG_NOTES (stack_reg_info[regno].last_use));
+     }
+   for (i = 0;
+        i < (int) stack_reg_info[regno].num_non_dead_store;
+        i++)
+     { /* Handle the stores of the stack register that were done
+          between insn and store_insn.  */
+       store_insn 
+ 	= stack_reg_info[regno].non_dead_store[i];
+       SET_SRC (PATTERN (store_insn)) = stack_slot;
+       if (GET_CODE (stack_slot) == REG )
+         {
+           reg_n_refs[REGNO (stack_slot)]++;
+           PUT_MODE (SET_DEST (PATTERN (store_insn)), GET_MODE (stack_slot));
+         }
+       INSN_CODE (store_insn) = recog (PATTERN (store_insn), store_insn, 0);
+     }
+   stack_reg_info[regno].store_insn = NULL;
+   stack_reg_info[regno].last_use = NULL;
+   stack_reg_info[regno].num_non_dead_store = 0;
+   stack_reg_info[regno].dies_at_store = 0;
+ }
+ 
+ 
+ 
+ /*
+   GET_CODE(mem) is MEM
+   we are interested in the insns between start_insn and stop_insn
+   (non inclusive)
+   return 1 if the address of mem or the contents of mem may POSSIBLY
+   be changed in this interval
+   return 0 otherwise
+     by address of mem changing we mean that mem contains a base and/or
+     index register and some insn in the interval sets the register.
+ */
+ static int
+ addr_or_val_changed (mem, start_insn, stop_insn)
+      rtx mem, start_insn, stop_insn;
+ {
+   rtx insn;
+   struct regs_mentioned *a_reg_mentioned;
+   char * storage;
+ 
+   if (MEM_VOLATILE_P (mem))
+     {
+       return (1);
+     }
+   /*
+   if (RTX_UNCHANGING_P (mem))
+     {
+       return (0);
+     } */
+   reg_mentioned_header = NULL;
+   storage = (char *) obstack_alloc (&momentary_obstack, 0);
+   find_regs_mentioned (mem);
+   for (insn = NEXT_INSN (start_insn); insn != stop_insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == CODE_LABEL)
+ 	{
+ 	  return (1);
+ 	}
+       if (GET_CODE (insn) == INSN)
+ 	{
+ 	  if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == CLOBBER)
+ 	    {
+ 	      if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
+ 		{
+ 		  if (true_dependence (mem, SET_DEST (PATTERN (insn))))
+ 		    {
+ 		      obstack_free (&momentary_obstack, storage);
+ 		      return (1);
+ 		    }
+ 		}
+ 	      else if (GET_CODE (SET_DEST (PATTERN (insn))) == REG)
+ 		{
+ 		  for (a_reg_mentioned = reg_mentioned_header;
+ 		       a_reg_mentioned != NULL;
+ 		       a_reg_mentioned = a_reg_mentioned->next)
+ 		    {
+ 		      if (reg_overlap_mentioned_p (SET_DEST (PATTERN (insn)),
+ 						   a_reg_mentioned->reg)
+ 			)
+ 			{
+   		          obstack_free (&momentary_obstack, storage);
+ 			  return (1);
+ 			}
+ 		    }
+ 		}
+ 	      else
+ 		{
+ 		  obstack_free (&momentary_obstack, storage);
+ 		  return (1);
+ 		}
+ 	    }
+ 	  else
+ 	    {
+ 	      obstack_free (&momentary_obstack, storage);
+ 	      return (1);
+ 	    }
+ 	}
+     }
+   obstack_free (&momentary_obstack, storage);
+   return (0);
+ }
+ 
+ 
+ /* Build a linked list of (struct regs_mentioned) describing the
+    registers used in the pattern pat.  
+ */
+ static void
+ find_regs_mentioned (pat)
+      rtx pat;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+   struct regs_mentioned *one_reg;
+ 
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+     case REG:
+       one_reg = (struct regs_mentioned *)
+ 	obstack_alloc (&momentary_obstack, sizeof (struct regs_mentioned));
+       one_reg->reg = pat;
+       one_reg->next = reg_mentioned_header;
+       reg_mentioned_header = one_reg;
+       return;
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return;
+ 
+ 
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    find_regs_mentioned (XVECEXP (pat, i, j));
+ 	}
+       else if (fmt[i] == 'e')
+ 	find_regs_mentioned (XEXP (pat, i));
+     }
+ }
+ 
+ 
+ /*
+   if insn stores a stack register into memory
+     set *regno to the register# stored
+     if the stack register is marked dead at the store
+       return 1
+     else
+       return 0
+ */
+ static int
+ stack_reg_dies_at_store (insn, regno)
+      rtx insn;
+      int *regno;
+ {
+   if (GET_CODE (SET_DEST (PATTERN (insn))) == MEM
+       && GET_CODE (SET_SRC (PATTERN (insn))) == REG
+       && IS_STACK_MODE (GET_MODE (SET_SRC (PATTERN (insn))))
+     )
+     {
+       *regno = REGNO (SET_SRC (PATTERN (insn)));
+       return ((int) find_regno_note (insn, REG_DEAD, *regno));
+     }
+   return (0);
+ }
+ 
+ 
+ /*
+   Record relevant information on each stack register that is mentioned
+   in pat which is a subexpression of insn.  
+ */
+ static void
+ mark_stack_regs_mentioned (pat, insn)
+      rtx pat, insn;
+ {
+   register char *fmt;
+   register int i;
+   register enum rtx_code code;
+ 
+   code = GET_CODE (pat);
+ 
+   switch (code)
+     {
+     case REG:
+       if (IS_STACK_MODE (GET_MODE (pat)))
+ 	{
+ 	  if (stack_reg_info[REGNO (pat)].last_use == NULL)
+ 	    {
+ 	      stack_reg_info[REGNO (pat)].last_use = insn;
+ 	    }
+ 	}
+       return;
+ 
+       /* These codes have no constituent expressions
+ 	 and are unique.  */
+     case SCRATCH:
+     case CC0:
+     case PC:
+     case QUEUED:
+     case CONST_INT:
+     case CONST_DOUBLE:
+     case SYMBOL_REF:
+     case CODE_LABEL:
+       return;
+ 
+ 
+     }
+ 
+ 
+   fmt = GET_RTX_FORMAT (code);
+ 
+   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+     {
+       if (fmt[i] == 'E')
+ 	{
+ 	  register int j;
+ 	  for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ 	    mark_stack_regs_mentioned (XVECEXP (pat, i, j), insn);
+ 	}
+       else if (fmt[i] == 'e')
+ 	mark_stack_regs_mentioned (XEXP (pat, i), insn);
+     }
+ }
+ 
+ 
+ /*
+    Stack mode registers that are set in one basic block and only
+    loaded to or stored from in successor blocks are replaced with
+    stack slots in the successor blocks. 
+ */
+ static void
+ func_stack_reg_to_stack_slot ()
+ {
+   rtx head, tail, target;
+   register regset tem;
+   int i, j, found, target_blocknum, regno, successful_visit, reg_defined_elsewhere,
+     reg_set_or_stored, cmprd, only_cmp;
+   char *storage;
+ #ifdef SPARE_REGS
+    int max_regno = max_reg_num ();
+ #endif
+ 
+ 
+   storage = (char *) obstack_alloc (&momentary_obstack, 0);
+   basic_block_maybe_live_at_end = (regset *) alloca (n_basic_blocks * sizeof (regset));
+   tem = (regset) obstack_alloc (&momentary_obstack, n_basic_blocks * regset_bytes);
+   bzero (tem, n_basic_blocks * regset_bytes);
+   init_regset_vector (basic_block_maybe_live_at_end, tem, n_basic_blocks, regset_bytes);
+   jump_target_block = (int *) alloca (n_basic_blocks * sizeof (int));
+   fall_thru_block = (int *) alloca (n_basic_blocks * sizeof (int));
+   blocks_visited = (char *) alloca (n_basic_blocks * sizeof (char));
+   death_blocks = (rtx *) alloca (n_basic_blocks * sizeof (rtx));
+   blocks_defined = (char *) alloca (n_basic_blocks * sizeof (char));
+   cmprd = 0;
+   only_cmp = 1;
+ 
+   if (stack_reg_dump_file)
+     {
+       fprintf (stack_reg_dump_file,
+ 	       "Offload stack regs:\n\n");
+     }
+   /* Find block successors */
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       jump_target_block[i] = -1;
+       fall_thru_block[i] = -1;
+       head = basic_block_head[i];
+       tail = basic_block_end[i];
+       if (GET_CODE (tail) == JUMP_INSN)
+ 	{
+ 	  target = JUMP_LABEL (tail);
+ 	  if (target == NULL)
+ 	    {
+ 	      return;
+ 	    }
+ 	  /* target is the head of the basic block jumped to
+              find which block it is */
+ 	  target_blocknum = 0;
+ 	  found = 0;
+ 	  while (target_blocknum < n_basic_blocks && !found)
+ 	    {
+ 	      if (basic_block_head[target_blocknum] == target)
+ 		{
+ 		  found = 1;
+ 		}
+ 	      else
+ 		{
+ 		  target_blocknum++;
+ 		}
+ 	    }
+ 	  if (!found)
+ 	    {
+ 	      return;
+ 	    }
+ 	  jump_target_block[i] = target_blocknum;
+ 	  for (j = 0; j < regset_size; j++)
+ 	    basic_block_maybe_live_at_end[i][j]
+ 	      |= basic_block_live_at_start[target_blocknum][j];
+ 	}
+       if (!simplejump_p (tail))
+ 	{
+ 	  if (i < n_basic_blocks - 1)
+ 	    {
+ 	      fall_thru_block[i] = i + 1;
+ 	      for (j = 0; j < regset_size; j++)
+ 		basic_block_maybe_live_at_end[i][j]
+ 		  |= basic_block_live_at_start[i + 1][j];
+ 	    }
+ 	}
+     }
+   if (stack_reg_dump_file)
+     my_dump_block_info ();
+   /* Do inter block optimizations */
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       for (regno = FIRST_PSEUDO_REGISTER; regno < max_regno; regno++)
+ 	{
+ 	  register int offset = regno / REGSET_ELT_BITS;
+ 	  register int bit = 1 << (regno % REGSET_ELT_BITS);
+ 	  if (stack_reg_dump_file
+ 	      && IS_STACK_MODE (GET_MODE (regno_reg_rtx[regno]))
+ 	      && (basic_block_maybe_live_at_end[i][offset] & bit)
+ 	      && !(basic_block_live_at_start[i][offset] & bit)
+ 	    )
+ 	    {
+ 	      fprintf (stack_reg_dump_file,
+ 		       "\nstack reg%d in block %d  d_a_p %d\n",
+ 		       regno, i,
+ 		       reg_dead_at_pred (offset, bit, i));
+ 	    }
+ 	  if ((basic_block_maybe_live_at_end[i][offset] & bit)
+ 	      && reg_dead_at_pred (offset, bit, i)
+ 	      && !(basic_block_live_at_start[i][offset] & bit)
+ 	      && IS_STACK_MODE (GET_MODE (regno_reg_rtx[regno])))
+ 	    {
+ 	      /* A stack register that is live at the exit of the
+                  block and not live on entry */
+ 	      if (stack_reg_dump_file)
+ 		{
+ 		  fprintf (stack_reg_dump_file,
+ 		  "\nstack reg%d in block %d live at end but not at start\n",
+ 			   regno, i);
+ 		}
+ 	      bzero (blocks_visited, n_basic_blocks * sizeof (char));
+ 	      bzero (death_blocks, n_basic_blocks * sizeof (rtx));
+ 	      num_visits = 0;
+ 	      successful_visit = visit_till_dies (regno, i);
+ 	      if (stack_reg_dump_file)
+ 		{
+ 		  fprintf (stack_reg_dump_file, " blocks visited : ");
+ 		  for (j = 0; j < n_basic_blocks; j++)
+ 		    {
+ 		      if (blocks_visited[j])
+ 			{
+ 			  fprintf (stack_reg_dump_file, "%d ", j);
+ 			}
+ 		    }
+ 		  fprintf (stack_reg_dump_file, "\n");
+ 		}
+ 	      successful_visit = 
+ 	        successful_visit && death_blocks_ok (regno);
+ 	      bzero (blocks_defined, n_basic_blocks * sizeof (char));
+ 	      blocks_defined[i] = 1;
+ 	      reg_defined_elsewhere = reg_def_in_unvisited (offset, bit, i);
+ 	      reg_set_or_stored 
+ 		= reg_only_set_or_stored (regno, i, &cmprd, &only_cmp);
+ 	      if (successful_visit
+ 		  && !reg_defined_elsewhere
+ 		  && reg_set_or_stored)
+ 		{  /* This reg was never used in any computation after
+                       this set until it's death - so don't keep
+                       it in stack reg after block i.  Allocate a temp slot
+                       for it and store it there at the end of block i.  
+                       In all visited blocks replace regno with this
+                       temp slot.  */
+ 		  if (stack_reg_dump_file)
+ 		    {
+ 		      fprintf (stack_reg_dump_file,
+ 			  " only loaded or stored in all visited blocks\n");
+ 		    }
+ 		  if (store_into_temp (regno, i))
+ 		    {
+ 		      if (stack_reg_dump_file)
+ 			{
+ 			  fprintf (stack_reg_dump_file,
+ 			  " replaced by temp slot in all blocks visited\n");
+ 			}
+ 		      replace_with_temp_slot (regno, i);
+ 		    }
+ 		}
+ 	      else if (successful_visit && cmprd)
+ 		{
+ 		  /* In each block where regno is defined by a computation
+                      store it and reload it to avoid precision problems
+                      in comparison */
+ 		  offload_reg (regno);
+ 		}
+ 	      if (stack_reg_dump_file)
+ 		{
+ 		  fprintf (stack_reg_dump_file,
+ 			   "  successful visit %d  cmprd %d\n", successful_visit, cmprd);
+ 		}
+ 	    }
+ 	}
+     }
+   obstack_free (&momentary_obstack, storage);
+ }
+ 
+ 
+ /*
+   The blocks where the stack reg dies on the visit have been
+   marked by death_blocks[block_num] being set to the NEXT_INSN
+   of the insn where it dies in the block.  
+   For each of these blocks either the register must not be redefined
+   in the block or none of the successors of the block have been
+   visited.  
+ */
+ 
+ static int
+ death_blocks_ok (regno)
+      int regno;
+ {
+   int i, successor_visited;
+ 
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       if (death_blocks[i])
+ 	{
+ 	  successor_visited = 0;
+ 	  if (fall_thru_block[i] != -1
+ 	      && blocks_visited[fall_thru_block[i]])
+ 	    {
+ 	      successor_visited = 1;
+ 	    }
+ 	  if (successor_visited == 0 && jump_target_block[i] != -1
+ 	      && blocks_visited[jump_target_block[i]])
+ 	    {
+ 	      successor_visited = 1;
+ 	    }
+ 	  if (successor_visited == 0)
+ 	    {
+ 	      continue;
+ 	    }
+ 	  else if (reg_set_between_p (regno_reg_rtx[regno],
+ 				      PREV_INSN (death_blocks[i]),
+ 				      NEXT_INSN (basic_block_end[i])))
+ 	    {
+ 	      return (0);
+ 	    }
+ 	}
+     }
+   return (1);
+ }
+ 
+ 
+ /*
+   Like offload_if_necessary but for stack registers used in equality
+   comparisons in one basic block and computed in another.  The offload
+   and reload are done at the place of computation.  
+ */
+ static void
+ offload_reg (regno)
+      int regno;
+ {
+   int block, reg_loaded;
+   rtx last_set_insn, new_insn;
+ 
+   if (stack_reg_dump_file)
+     {
+       fprintf (stack_reg_dump_file,
+ 	       "offload compared reg %d\n", regno);
+     }
+   for (block = 0; block < n_basic_blocks; block++)
+     {
+       if (blocks_defined[block])
+ 	{
+ 	  if (stack_reg_dump_file)
+ 	    {
+ 	      fprintf (stack_reg_dump_file,
+ 		       " defined in block %d\n", block);
+ 	    }
+ 	  last_set_insn = NULL;
+ 	  reg_loaded 
+ 	    = reg_last_loaded (block, basic_block_end[block], regno, &last_set_insn);
+ 	  if (stack_reg_dump_file)
+ 	    {
+ 	      fprintf (stack_reg_dump_file,
+ 		       "  reg loaded %d ", reg_loaded);
+ 	      if (last_set_insn)
+ 		fprintf (stack_reg_dump_file,
+ 			 " last_set_insn %d", INSN_UID (last_set_insn));
+ 	      fprintf (stack_reg_dump_file, "\n");
+ 	    }
+ 	  if (reg_loaded == 0 && last_set_insn)
+ 	    {
+ 	      if (stack_reg_dump_file)
+ 		{
+ 		  fprintf (stack_reg_dump_file,
+ 			   "   actually offloading\n");
+ 		}
+ 	      if (reg_temp_slot[regno] == NULL)
+ 		{
+ 		  reg_temp_slot[regno] 
+ 		    = assign_stack_local (GET_MODE (regno_reg_rtx[regno]),
+ 			    GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno])),
+ 					-1);
+ 		}
+ 	      MEM_VOLATILE_P (reg_temp_slot[regno]) = 1;
+ 	      new_insn 
+ 		= emit_insn_before (
+ 				   gen_rtx (SET, 0,
+ 				reg_temp_slot[regno], regno_reg_rtx[regno]),
+ 				   NEXT_INSN (last_set_insn));
+ 	      REG_NOTES (new_insn) 
+ 	        = gen_rtx (EXPR_LIST, REG_DEAD,
+ 			 regno_reg_rtx[regno],
+ 			 REG_NOTES (new_insn));
+ 	      reg_n_deaths[regno]++;
+ 	      new_insn 
+ 		= emit_insn_before (
+ 				   gen_rtx (SET, 0,
+ 				regno_reg_rtx[regno], reg_temp_slot[regno]),
+ 				   NEXT_INSN (new_insn));
+ 	      if (basic_block_end[block] == last_set_insn)
+ 		{
+ 		  basic_block_end[block] = new_insn;
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ /*
+   If the reg given by offset an bit in the live vecotrs is not live
+   at the end of any blocks that are the predecessors of blocknum
+   (except blocknum itself)
+     return 1
+   else
+     return 0
+ */
+ static int
+ reg_dead_at_pred (offset, bit, blocknum)
+      int offset, bit, blocknum;
+ {
+   rtx head, jump;
+   int i;
+ 
+   head = basic_block_head[blocknum];
+ 
+   if (GET_CODE (head) == CODE_LABEL)
+     for (jump = LABEL_REFS (head);
+ 	 jump != head;
+ 	 jump = LABEL_NEXTREF (jump))
+       {
+ 	for (i = 0; i < n_basic_blocks; i++)
+ 	  {
+ 	    if (basic_block_end[i] == CONTAINING_INSN (jump))
+ 	      break;
+ 	  }
+ 	if (i == n_basic_blocks)
+ 	  {
+ 	    return (0);
+ 	  }
+ 	if (i != blocknum)
+ 	  {
+ 	    if (basic_block_maybe_live_at_end[i][offset] & bit)
+ 	      {
+ 		return (0);
+ 	      }
+ 	  }
+       }
+ 
+   if ((blocknum - 1) == -1 ||
+       simplejump_p (basic_block_end[blocknum - 1]) ||
+       !(basic_block_maybe_live_at_end[blocknum - 1][offset] & bit))
+     {
+       return (1);
+     }
+   return (0);
+ 
+ }
+ 
+ /*
+   If the definition of the register in some visited block is
+   done by a block that has not been visited then return 1
+ */
+ static int
+ reg_def_in_unvisited (offset, bit, blocknum)
+      int offset, bit, blocknum;
+ {
+   int i, j, ret_val;
+   rtx head, jump;
+ 
+   ret_val = 0;
+ 
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       if (i != blocknum && blocks_visited[i])
+ 	{
+ 	  head = basic_block_head[i];
+ 
+ 	  if (GET_CODE (head) == CODE_LABEL)
+ 	    for (jump = LABEL_REFS (head);
+ 		 jump != head;
+ 		 jump = LABEL_NEXTREF (jump))
+ 	      {
+ 		for (j = 0; j < n_basic_blocks; j++)
+ 		  {
+ 		    if (basic_block_end[j] == CONTAINING_INSN (jump))
+ 		      break;
+ 		  }
+ 		if (j == n_basic_blocks)
+ 		  {
+ 		    ret_val = 1;
+ 		  }
+ 		if (blocks_visited[j] == 0 && j != i)
+ 		  {
+ 		    if (basic_block_maybe_live_at_end[j][offset] & bit)
+ 		      {
+ 			blocks_defined[j] = 1;
+ 			ret_val = 1;
+ 		      }
+ 		  }
+ 	      }
+ 
+ 	  if ((i - 1) != -1
+ 	      && !simplejump_p (basic_block_end[i - 1])
+ 	      && blocks_visited[i - 1] == 0
+ 	      && basic_block_maybe_live_at_end[i - 1][offset] & bit)
+ 	    {
+ 	      blocks_defined[i - 1] = 1;
+ 	      ret_val = 1;
+ 	    }
+ 	}
+     }
+   return (ret_val);
+ }
+ 
+ 
+ /* regno is never used in any computation from it's set in
+    source_blocknum until it's death - so don't keep
+    it in stack reg after source_blocknum.  Allocate a temp slot
+    for it and store it there at the end of block source_blocknum.
+    In all visited blocks replace regno with this temp slot. 
+    In blocks where regno dies the replacement is done
+    up until the insn in which regno dies.  
+ */
+ static void
+ replace_with_temp_slot (regno, source_blocknum)
+ {
+   int i, had_call, num_insns;
+   rtx insn, note;
+   register int offset = regno / REGSET_ELT_BITS;
+   register int bit = 1 << (regno % REGSET_ELT_BITS);
+   register int compl_bit;
+ 
+   compl_bit = ~bit;
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       if (blocks_visited[i] && i != source_blocknum)
+ 	{
+ 	  basic_block_live_at_start[i][offset] &= compl_bit;
+ 	  if (!death_blocks[i])
+ 	    {
+ 	      basic_block_maybe_live_at_end[i][offset] &= compl_bit;
+ 	    }
+ 	  had_call = 0;
+ 	  num_insns = 0;
+ 	  for (insn = basic_block_head[i];
+ 	       insn && insn != death_blocks[i]
+ 	       && insn != NEXT_INSN (basic_block_end[i]);
+ 	       insn = NEXT_INSN (insn))
+ 	    {
+ 	      num_insns++;
+ 	      if (GET_CODE (insn) == CALL_INSN)
+ 	        had_call = 1;
+ 	      if (GET_CODE (insn) == INSN)
+ 		{
+ 		  init_undo_buf ();
+ 		  subst_in_insn (insn, PATTERN (insn), regno_reg_rtx[regno],
+ 				 reg_temp_slot[regno], 0, 0);
+ 		  if (GET_CODE (reg_temp_slot[regno]) == REG
+ 		      && GET_CODE (PATTERN (insn)) == SET)
+ 		    {
+ 	              register int n_offset = 
+ 	                REGNO (reg_temp_slot[regno]) / REGSET_ELT_BITS;
+ 	              register REGSET_ELT_TYPE n_bit
+ 	                = (REGSET_ELT_TYPE) 1 
+ 	                  << (REGNO (reg_temp_slot[regno]) % REGSET_ELT_BITS);
+ 	              basic_block_live_at_start[i][n_offset] |= n_bit;
+ 	              reg_basic_block[REGNO (reg_temp_slot[regno])] = REG_BLOCK_GLOBAL;
+ 		      if (rtx_equal_p (reg_temp_slot[regno], 
+ 		                       SET_DEST (PATTERN (insn))))
+ 		        {
+ 		          reg_n_sets[REGNO (reg_temp_slot[regno])]++;
+ 		          reg_n_refs[REGNO (reg_temp_slot[regno])]++;
+                           if (GET_CODE (SET_SRC (PATTERN (insn)))
+                               == CONST_DOUBLE)
+                             {
+                               union
+                                 {
+                                   int i[2];
+                                   double d;
+                                 }
+                               u1;
+                               union
+                                 {
+                                   int i;
+                                   float f;
+                                 }
+                               u2;
+                               u1.i[0] = 
+                                 CONST_DOUBLE_LOW (SET_SRC (PATTERN (insn)));
+                               u1.i[1] = 
+                                 CONST_DOUBLE_HIGH (SET_SRC (PATTERN (insn)));
+                               u2.f = u1.d;
+                               SET_SRC (PATTERN (insn)) = 
+                                 gen_rtx (CONST_INT, 0, u2.i);
+                             }
+                           else
+                             {
+ 		              PUT_MODE (SET_SRC (PATTERN (insn)), 
+ 		                    GET_MODE (reg_temp_slot[regno]));
+ 
+ 		            }
+ 		        }
+ 		      if (rtx_equal_p (reg_temp_slot[regno], 
+ 		                       SET_SRC (PATTERN (insn))))
+ 		        {
+ 		          PUT_MODE (SET_DEST (PATTERN (insn)), 
+ 		                    GET_MODE (reg_temp_slot[regno]));
+ 		          reg_live_length[REGNO (reg_temp_slot[regno])] 
+ 		            += num_insns;
+ 		          reg_n_refs[REGNO (reg_temp_slot[regno])]++;
+ 		          if (had_call)
+ 		            {
+ 		              reg_n_calls_crossed[REGNO (reg_temp_slot[regno])]++;
+ 		            }
+ 		        }
+ 		    }
+ 		  INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
+ 		  if ((note = find_regno_note (insn, REG_DEAD, regno)) != NULL)
+ 		    {
+ 		      if (GET_CODE (reg_temp_slot[regno]) == REG)
+ 		        {
+ 		          XEXP (note, 0) = reg_temp_slot[regno];
+ 		          reg_n_deaths[REGNO (reg_temp_slot[regno])]++;
+ 		        }
+ 		      else
+ 		        remove_note (insn, note);
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ 
+ 
+ /*
+   If in each block_visited (except source_blocknum) regno is only
+   set, or used as a source in a store then
+     return 1
+   else
+     return 0
+   *used_in_cmp is set to 1 if regno is used in a comparison
+   in a block and it was not last set by a load before that
+   comparison
+   *only_cmp is set to 1 if the only other use of regno besides
+   as a dest or source of a store is in comparison, otherwise it
+   is set to 0
+ */
+ static int
+ reg_only_set_or_stored (regno, source_blocknum, used_in_cmp, only_cmp)
+      int regno, source_blocknum, *used_in_cmp, *only_cmp;
+ {
+   int i, ret_val;
+   rtx insn, cmp_part, last_set_insn;
+ 
+   ret_val = 1;
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       if (blocks_visited[i] && i != source_blocknum)
+ 	{
+ 	  for (insn = basic_block_head[i];
+ 	       insn && insn != death_blocks[i]
+ 	       && insn != NEXT_INSN (basic_block_end[i]);
+ 	       insn = NEXT_INSN (insn))
+ 	    {
+ 	      if (GET_CODE (insn) == INSN)
+ 		{
+ 		  if (reg_used_in_body (regno, PATTERN (insn)))
+ 		    {
+ 		      ret_val = 0;
+ 		      if (stack_reg_dump_file)
+ 			{
+ 			  fprintf (stack_reg_dump_file,
+ 				   "  reg used in body of insn %d\n", INSN_UID (insn));
+ 			}
+ 		      if (GET_CODE (PATTERN (insn)) == PARALLEL
+ 			&& GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
+ 			{
+ 			  cmp_part = XVECEXP (PATTERN (insn), 0, 0);
+ 			  last_set_insn = NULL;
+ 			  if (SET_DEST (cmp_part) == cc0_rtx
+ 			      && GET_CODE (SET_SRC (cmp_part)) == COMPARE
+ 			      && (GET_MODE (SET_SRC (cmp_part)) == CCmode
+ 			          || GET_MODE (SET_SRC (cmp_part)) == CCFPEQmode
+ 			          || GET_MODE (SET_SRC (cmp_part)) == VOIDmode)
+ 			      && GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
+ 			      && REGNO (XEXP (SET_SRC (cmp_part), 0)) == regno
+ 			      && (GET_CODE (XEXP (SET_SRC (cmp_part), 1)) != REG
+ 			          || GET_MODE (SET_SRC (cmp_part)) == CCFPEQmode)
+ 			      && !reg_last_loaded (i, PREV_INSN (insn),
+ 				       REGNO (XEXP (SET_SRC (cmp_part), 0)),
+ 						   &last_set_insn)
+ 			      && !last_set_insn
+ 			      && tests_equality (NEXT_INSN (insn)))
+ 			    {
+ 			      *used_in_cmp = 1;
+ 			    }
+ 			  else
+ 			    {
+ 			      *only_cmp = 0;
+ 			    }
+ 			}
+ 		      else
+ 			{
+ 			  *only_cmp = 0;
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+   return (ret_val);
+ }
+ 
+ /*
+   If regno is used in insn is anyway except as a dest or source of a set
+     return 1
+   else
+     return 0
+ */
+ static int
+ reg_used_in_body (regno, body)
+      int regno;
+      rtx body;
+ {
+   int i, ret_val = 0;
+ 
+   if (GET_CODE (body) == SET)
+     {
+       if (GET_CODE (SET_DEST (body)) != REG)
+ 	{
+ 	  if (reg_overlap_mentioned_p (regno_reg_rtx[regno],
+ 				       SET_DEST (body)))
+ 	    {
+ 	      return (1);
+ 	    }
+ 	}
+       else if (REGNO (SET_DEST (body)) == regno)
+ 	{
+ 	  if (GET_CODE (SET_SRC (body)) != MEM
+ 	      && GET_CODE (SET_SRC (body)) != REG
+ 	      && GET_CODE (SET_SRC (body)) != CONST_DOUBLE)
+ 	    {
+ 	      return (1);
+ 	    }
+ 	}
+ 
+       if (GET_CODE (SET_SRC (body)) != REG)
+ 	{
+ 	  if (reg_overlap_mentioned_p (regno_reg_rtx[regno],
+ 				       SET_SRC (body)))
+ 	    {
+ 	      return (1);
+ 	    }
+ 	}
+       else if (REGNO (SET_SRC (body)) == regno)
+ 	{
+ 	  if (/*GET_CODE (SET_DEST (body)) != REG
+ 	      && */ GET_CODE (SET_DEST (body)) != MEM)
+ 	    {
+ 	      return (1);
+ 	    }
+ 	}
+       return (0);
+     }
+   else if (GET_CODE (body) == CLOBBER)
+     {
+       if (GET_CODE (SET_DEST (body)) == REG && REGNO (SET_DEST (body)) == regno)
+ 	{
+ 	  return (1);
+ 	}
+       return (0);
+     }
+   else if (GET_CODE (body) == PARALLEL)
+     {
+       for (i = 0; i < XVECLEN (body, 0); i++)
+ 	{
+ 	  ret_val |= reg_used_in_body (regno, XVECEXP (body, 0, i));
+ 	  if (ret_val)
+ 	    {
+ 	      return (1);
+ 	    }
+ 	}
+       return (ret_val);
+     }
+   else
+     {
+       return (1);
+     }
+ }
+ 
+ /*
+    If the stack reg regno has not already been allocated a temp slot then
+      allocate one for it. 
+    Store the last value of regno in block# source_blocknum into it's
+    temp_slot.  
+    Mark the last use of regno in the block as REG_DEAD
+ */
+ static int
+ store_into_temp (regno, source_blocknum)
+      int regno, source_blocknum;
+ {
+   rtx last_set, last_use, stack_slot, store_rtx, store_insn, note;
+   int found, insn_code_num, i;
+   register int offset;
+   register int bit;
+   register int compl_bit;
+ 
+ 
+   /* Find where regno is last set in source_blocknum */
+   last_set = basic_block_end[source_blocknum];
+   found = 0;
+   while (!found && last_set != PREV_INSN (basic_block_head[source_blocknum]))
+     {
+       if (GET_CODE (last_set) == INSN)
+ 	{
+ 	  if (GET_CODE (PATTERN (last_set)) == PARALLEL)
+ 	    {
+ 	      for (i = 0; i < XVECLEN (PATTERN (last_set), 0); i++)
+ 		{
+ 		  if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == SET)
+ 		    {
+ 		      if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
+ 			  REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
+ 			{
+ 			  return (0);
+ 			}
+ 		    }
+ 		  else if (GET_CODE (XVECEXP (PATTERN (last_set), 0, i)) == CLOBBER)
+ 		    {
+ 		      if (GET_CODE (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == REG &&
+ 			  REGNO (SET_DEST (XVECEXP (PATTERN (last_set), 0, i))) == regno)
+ 			{
+ 			  return (0);
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      return (0);
+ 		    }
+ 		}
+ 	    }
+ 	  if ((GET_CODE (PATTERN (last_set)) == SET ||
+ 	       GET_CODE (PATTERN (last_set)) == CLOBBER) &&
+ 	      GET_CODE (SET_DEST (PATTERN (last_set))) == REG &&
+ 	      REGNO (SET_DEST (PATTERN (last_set))) == regno)
+ 	    {
+ 	      if (GET_CODE (PATTERN (last_set)) == CLOBBER)
+ 		return (0);
+ 	      if (GET_CODE (SET_SRC (PATTERN (last_set))) != MEM)
+ 		return (0);
+ 	      found = 1;
+ 	    }
+ 	}
+       if (!found)
+ 	{
+ 	  last_set = PREV_INSN (last_set);
+ 	}
+     }
+   if (!found)
+     {
+       return (0);
+     }
+ 
+ 
+   /* Allocate a temp slot and store the value that is loaded into
+      regno at last_set into that temp slot and place the insn to
+      do this right after the load to regno */
+   if (reg_temp_slot[regno] == NULL)
+     {
+ #ifdef SPARE_REGS
+       if (max_reg_num () < max_regno)
+         {
+           if (GET_MODE (SET_DEST (PATTERN (last_set))) == SFmode)
+             {
+               reg_temp_slot[regno] = gen_reg_rtx (SImode);
+             }
+           else
+             reg_temp_slot[regno] 
+ 	      = assign_stack_local (GET_MODE (SET_DEST (PATTERN (last_set))),
+ 		   GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (last_set)))),
+ 			    -1);
+         }
+       else
+ #endif
+         reg_temp_slot[regno] 
+ 	  = assign_stack_local (GET_MODE (SET_DEST (PATTERN (last_set))),
+ 		   GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (last_set)))),
+ 			    -1);
+     }
+   store_rtx = gen_rtx (SET, 0, reg_temp_slot[regno],
+ 		       copy_rtx (SET_SRC (PATTERN (last_set))));
+   if (GET_CODE (reg_temp_slot[regno]) == REG )
+     {
+       if (GET_CODE (SET_SRC (store_rtx)) == CONST_DOUBLE)
+         {
+           union
+             {
+               int i[2];
+               double d;
+             }
+           u1;
+           union
+             {
+               int i;
+               float f;
+             }
+           u2;
+           u1.i[0] = CONST_DOUBLE_LOW (SET_SRC (store_rtx));
+           u1.i[1] = CONST_DOUBLE_HIGH (SET_SRC (store_rtx));
+           u2.f = u1.d;
+           SET_SRC (store_rtx) = 
+             gen_rtx (CONST_INT, 0, u2.i);
+         }
+       else
+         {
+           PUT_MODE (SET_SRC (store_rtx), GET_MODE (reg_temp_slot[regno]));
+         }
+       reg_n_sets[REGNO (reg_temp_slot[regno])]++;
+       reg_n_refs[REGNO (reg_temp_slot[regno])]++;
+       reg_live_length[REGNO (reg_temp_slot[regno])] = 2;
+     }
+   insn_code_num = recog (store_rtx, last_set);
+   if (insn_code_num < 0)
+     {
+       return (0);
+     }
+   store_insn = emit_insn_after (store_rtx, PREV_INSN (last_set));
+   INSN_CODE (store_insn) = insn_code_num;
+ 
+   /* Find where regno is last use in source_blocknum */
+   last_use = basic_block_end[source_blocknum];
+   found = 0;
+   while (!found && last_use != PREV_INSN (basic_block_head[source_blocknum]))
+     {
+       if (GET_CODE (last_use) == INSN)
+ 	{
+ 	  if (reg_overlap_mentioned_p (regno_reg_rtx[regno], PATTERN (last_use)))
+ 	    {
+ 	      found = 1;
+ 	    }
+ 	}
+       if (!found)
+ 	{
+ 	  last_use = PREV_INSN (last_use);
+ 	}
+     }
+   offset = regno / REGSET_ELT_BITS;
+   bit = 1 << (regno % REGSET_ELT_BITS);
+   compl_bit = ~bit;
+   if (!found)
+     { /* regno was only loaded and never used - the load can be deleted */
+       delete_insn_for_stacker (last_set);
+       basic_block_maybe_live_at_end[source_blocknum][offset] &= compl_bit;
+       return (1);
+     }
+   /* Mark regno as dead at last_use */
+   note = gen_rtx (EXPR_LIST, REG_DEAD, regno_reg_rtx[regno],
+ 		  REG_NOTES (last_use));
+   XEXP (note, 1) = REG_NOTES (last_use);
+   REG_NOTES (last_use) = note;
+   basic_block_maybe_live_at_end[source_blocknum][offset] &= compl_bit;
+   return (1);
+ }
+ 
+ 
+ /*
+   Starting at block# block_num visit all successor blocks recursively
+   stopping at a block where regno is not live at exit or regno
+   is set in block
+ */
+ static int
+ visit_till_dies (regno, block_num)
+      int regno, block_num;
+ {
+   register int offset = regno / REGSET_ELT_BITS;
+   register int bit = 1 << (regno % REGSET_ELT_BITS);
+   int ret_val = 1;
+   int already_visited;
+   rtx reg_death = NULL;
+ 
+   already_visited = blocks_visited[block_num];
+   blocks_visited[block_num] = 1;
+   if (num_visits > n_basic_blocks * 2)
+     { /* Failed to find where regno dies */
+       return (0);
+     }
+   if (already_visited)
+     {
+       num_visits++;
+       return (1);
+     }
+   num_visits++;
+   if ((basic_block_maybe_live_at_end[block_num][offset] & bit)
+       && !(reg_death = reg_dies_in_block (regno, block_num)))
+     {
+       if (jump_target_block[block_num] != -1)
+ 	{
+ 	  ret_val = visit_till_dies (regno, jump_target_block[block_num]);
+ 	}
+       if (ret_val && fall_thru_block[block_num] != -1)
+ 	{
+ 	  ret_val = visit_till_dies (regno, fall_thru_block[block_num]);
+ 	}
+       return (ret_val);
+     }
+   else
+     {
+       if (reg_death)
+ 	{
+ 	  death_blocks[block_num] = NEXT_INSN (reg_death);
+ 	}
+       return (1);
+     }
+ }
+ 
+ 
+ /* Return the insn where regno dies in the block if it does,
+    otherwise return NULL
+ */
+ static rtx
+ reg_dies_in_block (regno, block_num)
+      int regno, block_num;
+ {
+   rtx insn;
+ 
+   for (insn = basic_block_head[block_num];
+        insn && insn != NEXT_INSN (basic_block_end[block_num]);
+        insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN && find_regno_note (insn, REG_DEAD, regno))
+ 	{
+ 	  return (insn);
+ 	}
+     }
+   return (NULL);
+ }
+ 
+ my_dump_block_info ()
+ {
+   int i;
+   int max_regno = max_reg_num();
+   for (i = 0; i < n_basic_blocks; i++)
+     {
+       register rtx head, jump;
+       register int regno;
+       fprintf (stack_reg_dump_file, "\nBasic block %d: first insn %d, last %d.\n",
+ 	       i,
+ 	       INSN_UID (basic_block_head[i]),
+ 	       INSN_UID (basic_block_end[i]));
+       /* The control flow graph's storage is freed
+ 	 now when flow_analysis returns.
+ 	 Don't try to print it if it is gone.  */
+       fprintf (stack_reg_dump_file, "Succesor blocks: %d %d\n",
+ 	       fall_thru_block[i], jump_target_block[i]);
+       fprintf (stack_reg_dump_file, "\nRegisters live at start:");
+       for (regno = 0; regno < max_regno; regno++)
+ 	{
+ 	  register int offset = regno / REGSET_ELT_BITS;
+ 	  register int bit = 1 << (regno % REGSET_ELT_BITS);
+ 	  if (basic_block_live_at_start[i][offset] & bit)
+ 	    {
+ 	      fprintf (stack_reg_dump_file, " %d", regno);
+ 	    }
+ 	}
+       fprintf (stack_reg_dump_file, "\n");
+       fprintf (stack_reg_dump_file, "Registers live at end:");
+       for (regno = 0; regno < max_regno; regno++)
+ 	{
+ 	  register int offset = regno / REGSET_ELT_BITS;
+ 	  register int bit = 1 << (regno % REGSET_ELT_BITS);
+ 	  if (basic_block_maybe_live_at_end[i][offset] & bit)
+ 	    {
+ 	      fprintf (stack_reg_dump_file, " %d", regno);
+ 	    }
+ 	}
+       fprintf (stack_reg_dump_file, "\n");
+     }
+   fprintf (stack_reg_dump_file, "\n");
+ }
+ 
+ #define   MINUS0  0x80000000
+ 
+ /*
+   change floating point compares to integer compares
+ */
+ 
+ void
+ float_to_int_cmp (f, allow_new_jumps)
+      rtx f;
+ {
+   union
+     {
+       int i[2];
+       double d;
+     }
+   u1;
+   union
+     {
+       int i;
+       float f;
+     }
+   u2;
+   int block, found, next_is_ok, rev_new_targets, const_is_zero, no_new_jump,
+       change_org_jump, new_org_cond, rev_org_targets, new_jump_cond,
+       make_new_lab, new_lab_true;
+   rtx insn, sf_reg, sf_dead_note, last_set, mem_loaded, int_cmp, cmp_part,
+       op1, next, org_jump_insn, double_const, tmp, new_jump,  new_jump_insn, 
+       new_label, new_label_insn, gen_cmpsi_1 ();
+ 
+   if (HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
+       || HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
+     {
+       return;
+     }
+   if (TARGET_IEEE_FP)
+     {
+       return;
+     }
+   insn = f;
+   for (insn; insn != NULL; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	{
+ 	  if (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
+ 	    {
+ 	      cmp_part = XVECEXP (PATTERN (insn), 0, 0);
+ 	      if (SET_DEST (cmp_part) == cc0_rtx
+ 		  && GET_CODE (SET_SRC (cmp_part)) == COMPARE
+ 		  && (GET_MODE (SET_SRC (cmp_part)) == CCmode
+ 		      || GET_MODE (SET_SRC (cmp_part)) == VOIDmode)
+ 		  && ( 
+ 		      (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == FLOAT_EXTEND
+ 		       && GET_CODE (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == REG
+ 		       && REGNO (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == FIRST_FLOAT_REG
+ 	               && GET_MODE (XEXP (XEXP (SET_SRC (cmp_part), 0), 0)) == SFmode)
+ 	              || /* Will have to make sure later it was loaded 
+ 	                    from SFmode */
+ 		      (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == REG
+ 		       && REGNO (XEXP (SET_SRC (cmp_part), 0)) == FIRST_FLOAT_REG
+ 	               && GET_MODE (XEXP (SET_SRC (cmp_part), 0)) == DFmode)
+ 	             )
+ 		  && GET_CODE (XEXP (SET_SRC (cmp_part), 1)) == MEM)
+ 		{
+ 		  if (CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (SET_SRC (cmp_part), 1), 0)))
+ 		    {
+ 		      double_const
+ 			= get_pool_constant (XEXP (XEXP (SET_SRC (cmp_part), 1), 0));
+ 		      if (GET_CODE (double_const) == CONST_DOUBLE)
+ 			{
+ 			  u1.i[0] = CONST_DOUBLE_LOW (double_const);
+ 			  u1.i[1] = CONST_DOUBLE_HIGH (double_const);
+ 			  u2.f = u1.d;
+ 			  if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) == FLOAT_EXTEND)
+ 			    sf_reg = XEXP (XEXP (SET_SRC (cmp_part), 0), 0);
+ 			  else
+ 			    sf_reg = XEXP (SET_SRC (cmp_part), 0);
+ 			  sf_dead_note
+ 			    = find_regno_note (insn, REG_DEAD, REGNO (sf_reg));
+ 			}
+ 		      else
+ 			{
+ 			  double_const = NULL;
+ 			  sf_dead_note = NULL;
+ 			}
+ 		    }
+ 		  else
+ 		    {
+ 		      double_const = NULL;
+ 		      sf_dead_note = NULL;
+ 		    }
+ 
+ 		  next_is_ok = 1;
+ 		  no_new_jump = 0;
+ 		  const_is_zero = 0;
+ 		  if (u1.d == 0.0)
+ 		    {  /* 0.0 needs special handling because -0.0 has
+ 		          a different representation */
+ 		      const_is_zero = 1;
+ 		      next_is_ok = 0;
+ 		      rev_new_targets = 0;
+ 		      change_org_jump = 0;
+ 		      rev_org_targets = 0;
+ 		      new_jump_cond = EQ;
+ 		      make_new_lab = 0;
+ 		      new_lab_true = 0;
+ 		      next = NEXT_INSN (insn);
+ 		      if (allow_new_jumps
+ 		          && GET_CODE (next) == JUMP_INSN
+ 		          && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
+ 			{
+ 			  org_jump_insn = next;
+ 			  if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LT
+ 			      && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      rev_new_targets = 1;
+ 			    }			  
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GT
+ 			      && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      rev_new_targets = 1;
+ 			      change_org_jump = 1;
+ 			      new_org_cond = LE;
+ 			      rev_org_targets = 1;
+ 			      no_new_jump = 1;
+ 			    } 
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ
+ 			      && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      new_jump_cond = NE;
+ 			      rev_new_targets = 1;
+ 			      /* The original jump will jump to the new
+ 			         label, that will be placed immediately
+ 			         after the new jump.  */
+ 			      make_new_lab = 1;
+ 			      /* The new label is to be jumped to
+ 			         if the condition is true */
+ 			      new_lab_true = 1;
+ 			    } 
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
+ 			      && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
+ 			      && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			      && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      change_org_jump = 1;
+ 			      new_org_cond = EQ;
+ 			      new_jump_cond = NE;
+ 			      /* The original jump will jump to the new
+ 			         label, that will be placed immediately
+ 			         after the new jump.  */
+ 			      make_new_lab = 1;
+ 			      /* The new label is to be jumped to
+ 			         if the condition is true */
+ 			      new_lab_true = 1;
+ 			    } 
+ 			  else if ((GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GE
+ 			            && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
+ 			            && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			            && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			           ||
+ 			           (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LT
+ 			            && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
+ 			            && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
+ 			            && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			            && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx))
+ 			    {
+ 			      next_is_ok = 1;
+ 			      change_org_jump = 1;
+ 			      new_org_cond = GE;
+ 			      new_jump_cond = NE;
+ 			      rev_new_targets = 1;
+ 			      /* The original jump will jump to the new
+ 			         label, that will be placed immediately
+ 			         after the new jump.  */
+ 			      make_new_lab = 1;
+ 			      /* The new label is to be jumped to
+ 			         if the condition is true */
+ 			      new_lab_true = 1;
+ 			    } 
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GT
+ 			           && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
+ 			           && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      no_new_jump = 1;
+ 			    }
+ 			  else if ((GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == GE
+ 			            || GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == EQ)
+ 			           && XEXP (SET_SRC (PATTERN (next)), 1) != pc_rtx
+ 			           && XEXP (SET_SRC (PATTERN (next)), 2) == pc_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			    }
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == NE
+ 			           && XEXP (SET_SRC (PATTERN (next)), 1) == pc_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 0) == cc0_rtx
+ 			           && XEXP (XEXP (SET_SRC (PATTERN (next)), 0), 1) == const0_rtx)
+ 			    {
+ 			      next_is_ok = 1;
+ 			    }
+ 			  else if (GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)) == LE)
+ 			    {
+ 			      next_is_ok = 1;
+ 			      no_new_jump = 1;
+ 			    }
+ 			}
+ 		    }
+ 		  if (sf_dead_note
+ 		      && next_is_ok
+ 		      && u1.d >= 0.0
+ 		      && ((double) u2.f == u1.d)
+ 		      && ((float) u1.d == u2.f))
+ 		    { /* Find where the sf_reg was loaded from.  */
+ 		      last_set = PREV_INSN (insn);
+ 		      found = 0;
+ 		      while (!found && last_set)
+ 			{
+ 			  if (GET_CODE (last_set) == INSN)
+ 			    {
+ 			      if (GET_CODE (PATTERN (last_set)) == SET
+ 				  && rtx_equal_p (sf_reg,
+ 					      SET_DEST (PATTERN (last_set)))
+ 			          &&
+ 			          (GET_CODE (SET_SRC (PATTERN (last_set))) 
+ 			              == MEM ||
+ 			           (GET_CODE (SET_SRC (PATTERN (last_set))) 
+ 			             == FLOAT_EXTEND 
+ 			            &&
+ 			            GET_CODE (XEXP (SET_SRC (PATTERN (last_set)),0))
+ 			                      == MEM)
+ 				  ))
+ 				{
+ 				  if (GET_CODE (SET_SRC (PATTERN (last_set))) 
+ 			               == FLOAT_EXTEND)
+ 			            {
+ 			              mem_loaded = 
+ 			                XEXP (SET_SRC (PATTERN (last_set)),0);
+ 				      found = 1;
+ 			            }
+ 			          else if (GET_CODE (XEXP (SET_SRC (cmp_part), 0)) 
+ 			                   == FLOAT_EXTEND)
+ 			            {
+ 			              mem_loaded = 
+ 			                SET_SRC (PATTERN (last_set));
+ 				      found = 1;
+ 			            }
+ 			          else
+ 			            {
+ 			              last_set = NULL;
+ 			            }
+ 				}
+ 		 	      else if (GET_CODE (PATTERN (last_set)) == SET
+ 		 	               && GET_CODE (SET_DEST (PATTERN (last_set)))
+ 		 	                   == REG
+ 		 	               && !IS_STACK_MODE (
+ 		 	                    GET_MODE (SET_DEST (PATTERN (last_set)))))
+ 		 	        {
+ 		 	          last_set = PREV_INSN (last_set);
+ 		 	        }
+ 			      else
+ 				last_set = NULL;
+ 			    }
+ 			  else if (GET_CODE (last_set) == NOTE)
+ 			    {
+ 			      last_set = PREV_INSN (last_set);
+ 			    }
+ 			  else
+ 			    last_set = NULL;
+ 			}
+ 		      if (last_set)
+ 			{
+ 			  op1 = gen_rtx (MEM, SImode, XEXP (mem_loaded,0));
+ 			  /* See if op1 is also in a register.  */
+ 			  if (next_nonnote_insn (last_set) == insn)
+ 			    {
+ 			      tmp = prev_nonnote_insn (last_set);
+ 			    }
+ 			  else
+ 			    {
+ 			      tmp = next_nonnote_insn (last_set);
+ 			      if (next_nonnote_insn (tmp) != insn)
+ 			        {
+ 			          tmp = NULL;
+ 			        }
+ 			    }
+ 			  if (tmp
+ 			      && GET_CODE (tmp) == INSN
+ 			      && GET_CODE (PATTERN (tmp)) == SET
+ 			      && GET_CODE (SET_DEST (PATTERN (tmp))) == REG
+ 			      && rtx_equal_p (op1, 
+ 			                      SET_SRC (PATTERN (tmp))))
+ 			    {
+ 			      op1 = SET_DEST (PATTERN (tmp));
+ 			    }
+ 			  int_cmp
+ 				= gen_cmpsi_1 (op1,
+ 					      gen_rtx (CONST_INT, 0, u2.i));
+ 			  PATTERN (insn) = int_cmp;
+ 			  INSN_CODE (insn) = recog (int_cmp, insn);
+ 			  remove_note (insn, sf_dead_note);
+ 			  reg_n_deaths[REGNO (sf_reg)]--;
+ 			  PUT_CODE (last_set, NOTE);
+ 			  NOTE_LINE_NUMBER (last_set) = NOTE_INSN_DELETED;
+ 			  NOTE_SOURCE_FILE (last_set) = 0;
+ 			  if (const_is_zero && change_org_jump)
+ 			    {
+ 			      PUT_CODE (XEXP (SET_SRC (PATTERN (org_jump_insn)), 0), 
+ 			                new_org_cond);  
+ 			      INSN_CODE (org_jump_insn)
+ 				= recog (PATTERN (org_jump_insn), org_jump_insn);
+ 			    }
+ 			  if (const_is_zero && rev_org_targets)
+ 			    {
+ 
+ 			      tmp = XEXP (SET_SRC (PATTERN (org_jump_insn)), 1);
+ 			      XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
+ 				    = XEXP (SET_SRC (PATTERN (org_jump_insn)), 2);
+ 			      XEXP (SET_SRC (PATTERN (org_jump_insn)), 2) = tmp;
+ 			      INSN_CODE (org_jump_insn)
+ 				= recog (PATTERN (org_jump_insn), org_jump_insn);
+ 			    }
+ 			  if (const_is_zero && !no_new_jump)
+ 			    {
+ 			      new_jump = copy_rtx (PATTERN (next));
+ 			      PUT_CODE (XEXP (SET_SRC (new_jump), 0), new_jump_cond);
+ 			      if (rev_new_targets)
+ 				{
+ 				  tmp = XEXP (SET_SRC (new_jump), 1);
+ 				  XEXP (SET_SRC (new_jump), 1)
+ 				    = XEXP (SET_SRC (new_jump), 2);
+ 				  XEXP (SET_SRC (new_jump), 2) = tmp;
+ 				}
+ 			      int_cmp
+ 				= gen_cmpsi_1 (op1,
+ 					    gen_rtx (CONST_INT, 0, MINUS0));
+ 			      int_cmp
+ 				= emit_insn_before (int_cmp, NEXT_INSN (next));
+ 			      INSN_CODE (int_cmp) = INSN_CODE (insn);
+ 			      new_jump_insn
+ 				= emit_jump_insn_after (new_jump, int_cmp);
+ 			      INSN_CODE (new_jump_insn)
+ 				= recog (new_jump, new_jump_insn);
+ 			    }
+ 			  if (const_is_zero && make_new_lab)
+ 			    {
+ 			      if (no_new_jump)
+ 			        abort ();
+                               new_label = gen_label_rtx ();
+                               new_label_insn 
+                                 = emit_label_after (new_label, new_jump_insn);
+                               ++LABEL_NUSES (new_label_insn);
+                               JUMP_LABEL (org_jump_insn) = new_label_insn;
+                               if (new_lab_true)
+                                 {
+ 			          XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
+ 			            = gen_rtx (LABEL_REF, VOIDmode, new_label);
+ 			          XEXP (SET_SRC (PATTERN (org_jump_insn)), 2)
+ 			            = pc_rtx;
+                                 }
+                               else
+                                 {
+ 			          XEXP (SET_SRC (PATTERN (org_jump_insn)), 1)
+ 			            = pc_rtx;
+ 			          XEXP (SET_SRC (PATTERN (org_jump_insn)), 2)
+ 			            = gen_rtx (LABEL_REF, VOIDmode, new_label);
+                                 }
+ 			      INSN_CODE (org_jump_insn)
+ 				 = recog (PATTERN (org_jump_insn), org_jump_insn);
+ 			    }
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ #endif
  #endif /* STACK_REGS */
diff -rNci gcc-2.7.2/reload.c gcc-2.7.2p/reload.c
*** gcc-2.7.2/reload.c	Sat Nov 11 13:23:54 1995
--- gcc-2.7.2p/reload.c	Tue Jan 23 09:25:30 1996
***************
*** 98,104 ****
  #include "hard-reg-set.h"
  #include "flags.h"
  #include "real.h"
- #include "output.h"
  
  #ifndef REGISTER_MOVE_COST
  #define REGISTER_MOVE_COST(x, y) 2
--- 98,103 ----
***************
*** 357,372 ****
  
    *picode = CODE_FOR_nothing;
  
-   /* If X is a paradoxical SUBREG, use the inner value to determine both the
-      mode and object being reloaded.  */
-   if (GET_CODE (x) == SUBREG
-       && (GET_MODE_SIZE (GET_MODE (x))
- 	  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
-     {
-       x = SUBREG_REG (x);
-       reload_mode = GET_MODE (x);
-     }
- 
    /* If X is a pseudo-register that has an equivalent MEM (actually, if it
       is still a pseudo-register by now, it *must* have an equivalent MEM
       but we don't want to assume that), use that equivalent when seeing if
--- 356,361 ----
***************
*** 735,741 ****
  {
    register int i;
    int dont_share = 0;
-   int dont_remove_subreg = 0;
    rtx *in_subreg_loc = 0, *out_subreg_loc = 0;
    int secondary_in_reload = -1, secondary_out_reload = -1;
    enum insn_code secondary_in_icode = CODE_FOR_nothing;
--- 724,729 ----
***************
*** 902,915 ****
  		  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (in)),
  				       GET_MODE (SUBREG_REG (in)))))))
      {
-       /* This relies on the fact that emit_reload_insns outputs the
- 	 instructions for input reloads of type RELOAD_OTHER in the same
- 	 order as the reloads.  Thus if the outer reload is also of type
- 	 RELOAD_OTHER, we are guaranteed that this inner reload will be
- 	 output before the outer reload.  */
        push_reload (SUBREG_REG (in), NULL_RTX, &SUBREG_REG (in), NULL_PTR,
  		   GENERAL_REGS, VOIDmode, VOIDmode, 0, 0, opnum, type);
-       dont_remove_subreg = 1;
      }
  
  
--- 890,897 ----
***************
*** 971,1006 ****
        outmode = GET_MODE (out);
      }
  
-   /* Similar issue for (SUBREG:M1 (REG:M2 ...) ...) for a hard register R where
-      either M1 is not valid for R or M2 is wider than a word but we only
-      need one word to store an M2-sized quantity in R.
- 
-      However, we must reload the inner reg *as well as* the subreg in
-      that case.  In this case, the inner reg is an in-out reload.  */
- 
-   if (out != 0 && GET_CODE (out) == SUBREG
-       && GET_CODE (SUBREG_REG (out)) == REG
-       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
-       && (! HARD_REGNO_MODE_OK (REGNO (SUBREG_REG (out)), outmode)
- 	  || (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
- 	      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
- 		  > UNITS_PER_WORD)
- 	      && ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
- 		   / UNITS_PER_WORD)
- 		  != HARD_REGNO_NREGS (REGNO (SUBREG_REG (out)),
- 				       GET_MODE (SUBREG_REG (out)))))))
-     {
-       /* This relies on the fact that emit_reload_insns outputs the
- 	 instructions for output reloads of type RELOAD_OTHER in reverse
- 	 order of the reloads.  Thus if the outer reload is also of type
- 	 RELOAD_OTHER, we are guaranteed that this inner reload will be
- 	 output after the outer reload.  */
-       dont_remove_subreg = 1;
-       push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out),
- 		   &SUBREG_REG (out), ALL_REGS, VOIDmode, VOIDmode, 0, 0,
- 		   opnum, RELOAD_OTHER);
-     }
- 
    /* If IN appears in OUT, we can't share any input-only reload for IN.  */
    if (in != 0 && out != 0 && GET_CODE (out) == MEM
        && (GET_CODE (in) == REG || GET_CODE (in) == MEM)
--- 953,958 ----
***************
*** 1011,1026 ****
       simplifies some of the cases below.  */
  
    if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
!       && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
!       && ! dont_remove_subreg)
      in = gen_rtx (REG, GET_MODE (in),
  		  REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
  
    /* Similarly for OUT.  */
    if (out != 0 && GET_CODE (out) == SUBREG
        && GET_CODE (SUBREG_REG (out)) == REG
!       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
!       && ! dont_remove_subreg)
      out = gen_rtx (REG, GET_MODE (out),
  		  REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
  
--- 963,976 ----
       simplifies some of the cases below.  */
  
    if (in != 0 && GET_CODE (in) == SUBREG && GET_CODE (SUBREG_REG (in)) == REG
!       && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER)
      in = gen_rtx (REG, GET_MODE (in),
  		  REGNO (SUBREG_REG (in)) + SUBREG_WORD (in));
  
    /* Similarly for OUT.  */
    if (out != 0 && GET_CODE (out) == SUBREG
        && GET_CODE (SUBREG_REG (out)) == REG
!       && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER)
      out = gen_rtx (REG, GET_MODE (out),
  		  REGNO (SUBREG_REG (out)) + SUBREG_WORD (out));
  
***************
*** 4120,4125 ****
--- 4070,4079 ----
  {
    register int regno;
    rtx tem;
+ #ifdef REWRITE_ADDRESS
+   /* intel1 */
+   rtx rewrite_address();
+ #endif
  
    /* If the address is a register, see if it is a legitimate address and
       reload if not.  We first handle the cases where we need not reload
***************
*** 4247,4261 ****
  	return 0;
      }
  
!   /* If we have address of a stack slot but it's not valid because the
!      displacement is too large, compute the sum in a register.
!      Handle all base registers here, not just fp/ap/sp, because on some
!      targets (namely SH) we can also get too large displacements from
!      big-endian corrections.  */
    else if (GET_CODE (ad) == PLUS
! 	   && GET_CODE (XEXP (ad, 0)) == REG
! 	   && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
! 	   && REG_OK_FOR_BASE_P (XEXP (ad, 0))
  	   && GET_CODE (XEXP (ad, 1)) == CONST_INT)
      {
        /* Unshare the MEM rtx so we can safely alter it.  */
--- 4201,4217 ----
  	return 0;
      }
  
!   /* If we have address of a stack slot but it's not valid
!      (displacement is too large), compute the sum in a register.  */
    else if (GET_CODE (ad) == PLUS
! 	   && (XEXP (ad, 0) == frame_pointer_rtx
! #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
! 	       || XEXP (ad, 0) == hard_frame_pointer_rtx
! #endif
! #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
! 	       || XEXP (ad, 0) == arg_pointer_rtx
! #endif
! 	       || XEXP (ad, 0) == stack_pointer_rtx)
  	   && GET_CODE (XEXP (ad, 1)) == CONST_INT)
      {
        /* Unshare the MEM rtx so we can safely alter it.  */
***************
*** 4383,4388 ****
--- 4339,4375 ----
  	}
      }
  
+   /* intel1 - even if one of the registers is still a pseudo
+              subst_reg_equivs may be able to substitute a
+              constant for it too */
+     else
+              
+     if (tem != ad && memory_address_p (mode, tem))
+       {
+         rtx tmp_rtx;
+         tmp_rtx = copy_rtx (tem);
+ 	/* Ok, we win that way.  Replace any additional eliminable
+ 	   registers.  */
+ 	subst_reg_equivs_changed = 0;
+ 	tmp_rtx = subst_reg_equivs (tmp_rtx);
+ #ifdef REWRITE_ADDRESS
+ 	if (!strict_memory_address_p (mode, tmp_rtx))
+ 	  {
+             tmp_rtx = gen_rtx (MEM, mode, tmp_rtx);
+             REWRITE_ADDRESS (tmp_rtx);
+             tmp_rtx = XEXP (tmp_rtx, 0);
+ 	  }
+ #endif
+ 
+ 	/* Make sure that didn't make the address invalid again.  */
+ 
+ 	if (strict_memory_address_p (mode, tmp_rtx))
+ 	  {
+ 	    *loc = tmp_rtx;
+ 	    return 0;
+ 	  }
+ 	
+       }
    /* If constants aren't valid addresses, reload the constant address
       into a register.  */
    if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
***************
*** 4609,4626 ****
  	  {
  	    op0 = SUBREG_REG (op0);
  	    code0 = GET_CODE (op0);
- 	    if (code0 == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER)
- 	      op0 = gen_rtx (REG, word_mode,
- 			     REGNO (op0) + SUBREG_WORD (orig_op0));
  	  }
  
  	if (GET_CODE (op1) == SUBREG)
  	  {
  	    op1 = SUBREG_REG (op1);
  	    code1 = GET_CODE (op1);
- 	    if (code1 == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER)
- 	      op1 = gen_rtx (REG, GET_MODE (op1),
- 			     REGNO (op1) + SUBREG_WORD (orig_op1));
  	  }
  
  	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE 
--- 4596,4607 ----
***************
*** 4882,4918 ****
        return 0;
  
      case SUBREG:
!       if (GET_CODE (SUBREG_REG (x)) == REG)
  	{
! 	  /* If this is a SUBREG of a hard register and the resulting register
! 	     is of the wrong class, reload the whole SUBREG.  This avoids
! 	     needless copies if SUBREG_REG is multi-word.  */
! 	  if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
! 	    {
! 	      int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
  
! 	      if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
! 		     : REGNO_OK_FOR_BASE_P (regno)))
! 		{
! 		  push_reload (x, NULL_RTX, loc, NULL_PTR,
! 			       context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
! 		  return 1;
! 		}
! 	    }
! 	  /* If this is a SUBREG of a pseudo-register, and the pseudo-register
! 	     is larger than the class size, then reload the whole SUBREG.  */
! 	  else
  	    {
! 	      enum reg_class class = (context
! 				      ? INDEX_REG_CLASS : BASE_REG_CLASS);
! 	      if (CLASS_MAX_NREGS (class, GET_MODE (SUBREG_REG (x)))
! 		  > reg_class_size[class])
! 		{
! 		  push_reload (x, NULL_RTX, loc, NULL_PTR, class,
! 			       GET_MODE (x), VOIDmode, 0, 0, opnum, type);
! 		  return 1;
! 		}
  	    }
  	}
        break;
--- 4863,4883 ----
        return 0;
  
      case SUBREG:
!       /* If this is a SUBREG of a hard register and the resulting register is
! 	 of the wrong class, reload the whole SUBREG.  This avoids needless
! 	 copies if SUBREG_REG is multi-word.  */
!       if (GET_CODE (SUBREG_REG (x)) == REG
! 	  && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
  	{
! 	  int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
  
! 	  if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
! 		 : REGNO_OK_FOR_BASE_P (regno)))
  	    {
! 	      push_reload (x, NULL_RTX, loc, NULL_PTR,
! 			   context ? INDEX_REG_CLASS : BASE_REG_CLASS,
! 			   GET_MODE (x), VOIDmode, 0, 0, opnum, type);
! 	      return 1;
  	    }
  	}
        break;
***************
*** 5193,5199 ****
  	       && refers_to_regno_for_reload_p (regno, endregno,
  						SUBREG_REG (SET_DEST (x)),
  						loc))
! 	      /* If the output is an earlyclobber operand, this is
  		 a conflict.  */
  	      || ((GET_CODE (SET_DEST (x)) != REG
  		   || earlyclobber_operand_p (SET_DEST (x)))
--- 5158,5164 ----
  	       && refers_to_regno_for_reload_p (regno, endregno,
  						SUBREG_REG (SET_DEST (x)),
  						loc))
! 	      /* If the ouput is an earlyclobber operand, this is
  		 a conflict.  */
  	      || ((GET_CODE (SET_DEST (x)) != REG
  		   || earlyclobber_operand_p (SET_DEST (x)))
***************
*** 5597,5608 ****
  	      goal_mem
  	      || need_stable_sp))
  	return 0;
- 
- #ifdef NON_SAVING_SETJMP 
-       if (NON_SAVING_SETJMP && GET_CODE (p) == NOTE
- 	  && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
- 	return 0;
- #endif
  
  #ifdef INSN_CLOBBERS_REGNO_P
        if ((valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
--- 5562,5567 ----
diff -rNci gcc-2.7.2/reload.h gcc-2.7.2p/reload.h
*** gcc-2.7.2/reload.h	Thu Jun 15 12:00:35 1995
--- gcc-2.7.2p/reload.h	Tue Jan 23 09:25:30 1996
***************
*** 235,237 ****
--- 235,249 ----
  
  /* Find the places where hard regs are live across calls and save them.  */
  extern void save_call_clobbered_regs PROTO((enum machine_mode));
+ /* intel1 */
+ #define MAX_RELOAD_STACK_SLOTS 100
+ struct reload_slot_info {
+     rtx  reload_stack_slot;
+     rtx  reload_insn;
+     rtx last_store;
+     int is_loaded_to_reg;
+     int stack_slot_pseudo_reg;
+     int cur_stack_offset;
+     char reload_stack_mode;
+     unsigned reload_slot_updated:1;
+     } ;
diff -rNci gcc-2.7.2/reload1.c gcc-2.7.2p/reload1.c
*** gcc-2.7.2/reload1.c	Sun Nov  5 16:22:22 1995
--- gcc-2.7.2p/reload1.c	Tue Jan 23 09:25:31 1996
***************
*** 34,40 ****
  #include "recog.h"
  #include "basic-block.h"
  #include "output.h"
- #include "real.h"
  
  /* This file contains the reload pass of the compiler, which is
     run after register allocation has been done.  It checks that
--- 34,39 ----
***************
*** 77,82 ****
--- 76,83 ----
  #ifndef MEMORY_MOVE_COST
  #define MEMORY_MOVE_COST(x) 4
  #endif
+ /* intel1 */
+ static int cur_stack_offset;
  
  /* During reload_as_needed, element N contains a REG rtx for the hard reg
     into which reg N has been reloaded (perhaps for a previous insn). */
***************
*** 268,273 ****
--- 269,277 ----
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free free
  
+ /* intel1 */
+ extern FILE * global_reg_dump_file;
+ 
  /* List of labels that must never be deleted.  */
  extern rtx forced_labels;
  
***************
*** 308,313 ****
--- 312,326 ----
  
  #define NUM_ELIMINABLE_REGS (sizeof reg_eliminate / sizeof reg_eliminate[0])
  
+ /* intel1 */
+ /* information for loop_after_global optimizations */
+ struct reload_slot_info reload_slots[MAX_RELOAD_STACK_SLOTS];
+ int num_reload_stack_slots=0;
+ static rtx treplace_insn = NULL_RTX;
+ 
+ /* is 1 is the pseudo has been spilled */
+ int * pseudo_spilled;
+ 
  /* Record the number of pending eliminations that have an offset not equal
     to their initial offset.  If non-zero, we use a new copy of each
     replacement result in any insns encountered.  */
***************
*** 372,377 ****
--- 385,392 ----
  static void inc_for_reload		PROTO((rtx, rtx, int));
  static int constraint_accepts_reg_p	PROTO((char *, rtx));
  static int count_occurrences		PROTO((rtx, rtx));
+ /* intel1 */
+ int is_a_param_slot();
  
  /* Initialize the reload pass once per compilation.  */
  
***************
*** 466,471 ****
--- 481,506 ----
    /* The basic block number currently being processed for INSN.  */
    int this_block;
  
+   /* intel1 */
+   /* intel1. Look for insns whose src is equal to dest and delete them.  */
+   for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
+     {
+       if (GET_CODE (insn) == INSN 
+           && GET_CODE (PATTERN (insn)) == SET
+           && !(GET_CODE (SET_SRC (PATTERN (insn))) == MEM
+                && MEM_VOLATILE_P (SET_SRC (PATTERN (insn))))
+           && rtx_equal_p (SET_SRC (PATTERN (insn)), SET_DEST (PATTERN (insn))))
+         {
+ 	  PUT_CODE (insn, NOTE);
+ 	  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 	  NOTE_SOURCE_FILE (insn) = 0;
+         }
+     }
+   num_reload_stack_slots = 0;
+   pseudo_spilled = (int *)alloca(max_regno*sizeof(int));
+   bzero(pseudo_spilled,max_regno*sizeof(int));
+   bzero(reload_slots,MAX_RELOADS*sizeof(struct reload_slot_info));
+ 
    /* Make sure even insns with volatile mem refs are recognizable.  */
    init_recog ();
  
***************
*** 814,819 ****
--- 849,857 ----
  
        num_not_at_initial_offset = 0;
  
+ 	  /* intel1 */
+ 	  cur_stack_offset = 0;
+ 
        bzero ((char *) &offsets_known_at[get_first_label_num ()], num_labels);
  
        /* Set a known offset for each forced label to be at the initial offset
***************
*** 1955,1960 ****
--- 1993,2034 ----
  
    reload_in_progress = 0;
  
+   /* intel1 */
+   for (insn = first; insn; insn = NEXT_INSN (insn))
+     {
+       if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET
+           && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+           && GET_CODE (SET_SRC (PATTERN (insn))) == REG)
+         {
+           if (REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
+               && REGNO (SET_SRC (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER
+               && reg_equiv_mem[REGNO (SET_SRC (PATTERN (insn)))]
+               && reg_renumber[REGNO (SET_SRC (PATTERN (insn)))] < 0
+               && RTX_IS_SPILL_P (reg_equiv_mem[REGNO (SET_SRC (PATTERN (insn)))])
+               && !RTX_IS_SPILL_P (insn))
+             {
+               RTX_IS_SPILL_P (insn) = 1;
+               SPILL_PSEUDO (insn) = REGNO (SET_SRC (PATTERN (insn)));
+             }
+           if (REGNO (SET_DEST (PATTERN (insn))) >= FIRST_PSEUDO_REGISTER
+               && REGNO (SET_SRC (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
+               && reg_equiv_mem[REGNO (SET_DEST (PATTERN (insn)))]
+               && reg_renumber[REGNO (SET_DEST (PATTERN (insn)))] < 0
+               && RTX_IS_SPILL_P (reg_equiv_mem[REGNO (SET_DEST (PATTERN (insn)))])
+               && !RTX_IS_SPILL_P (insn))
+             {
+               RTX_IS_SPILL_P (insn) = 1;
+               SPILL_PSEUDO (insn) = REGNO (SET_DEST (PATTERN (insn)));
+             }
+   if (scratch_list)
+     free (scratch_list);
+   scratch_list = 0;
+   if (scratch_block)
+     free (scratch_block);
+   scratch_block = 0;
+ 
+         }
+     }
    /* Now eliminate all pseudo regs by modifying them into
       their equivalent memory references.
       The REG-rtx's for the pseudos are modified in place,
***************
*** 2016,2028 ****
    reg_equiv_constant = 0;
    reg_equiv_memory_loc = 0;
  
!   if (scratch_list)
!     free (scratch_list);
!   scratch_list = 0;
!   if (scratch_block)
!     free (scratch_block);
!   scratch_block = 0;
! 
    return failure;
  }
  
--- 2090,2106 ----
    reg_equiv_constant = 0;
    reg_equiv_memory_loc = 0;
  
!   /* intel1 */
!   if (num_reload_stack_slots == MAX_RELOAD_STACK_SLOTS)
!     { /* Too many so don't use any */
!       for (insn = first; insn ; insn = next_nonnote_insn (insn))
!         {
!           if (GET_CODE (insn) == INSN )
!             {
!               RTX_IS_SPILL_P (insn) = 0;
!             }
!         }
!     }
    return failure;
  }
  
***************
*** 2325,2330 ****
--- 2403,2417 ----
    REGNO (regno_reg_rtx[i])
      = reg_renumber[i] >= 0 ? reg_renumber[i] : i;
  
+   /* intel1 */
+   if (reg_renumber[i] < 0 
+       && reg_equiv_memory_loc[i] != 0
+       && is_a_param_slot (reg_equiv_memory_loc[i]))
+     {
+       pseudo_spilled[i] = 1;
+       RTX_IS_SPILL_P (reg_equiv_memory_loc[i]) = 1;
+       RTX_IS_SPILL_P (XEXP (reg_equiv_memory_loc[i], 0)) = 1;
+     }
    /* If we have a pseudo that is needed but has no hard reg or equivalent,
       allocate a stack slot for it.  */
  
***************
*** 2338,2343 ****
--- 2425,2432 ----
        int total_size = MAX (inherent_size, reg_max_ref_width[i]);
        int adjust = 0;
  
+       /* intel1 */
+       pseudo_spilled[i] = 1;
        /* Each pseudo reg has an inherent size which comes from its own mode,
  	 and a total size which provides room for paradoxical subregs
  	 which refer to the pseudo reg in wider modes.
***************
*** 2350,2362 ****
  	{
  	  /* No known place to spill from => no slot to reuse.  */
  	  x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size, -1);
  	  if (BYTES_BIG_ENDIAN)
  	    /* Cancel the  big-endian correction done in assign_stack_local.
  	       Get the address of the beginning of the slot.
  	       This is so we can do a big-endian correction unconditionally
  	       below.  */
  	    adjust = inherent_size - total_size;
- 
  	  RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  	}
        /* Reuse a stack slot if possible.  */
--- 2439,2453 ----
  	{
  	  /* No known place to spill from => no slot to reuse.  */
  	  x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size, -1);
+ 	  /* intel1 */
+ 	  RTX_IS_SPILL_P (x) = 1;
+ 	  RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  	  if (BYTES_BIG_ENDIAN)
  	    /* Cancel the  big-endian correction done in assign_stack_local.
  	       Get the address of the beginning of the slot.
  	       This is so we can do a big-endian correction unconditionally
  	       below.  */
  	    adjust = inherent_size - total_size;
  	  RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
  	}
        /* Reuse a stack slot if possible.  */
***************
*** 2364,2370 ****
--- 2455,2463 ----
  	       && spill_stack_slot_width[from_reg] >= total_size
  	       && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
  		   >= inherent_size))
+         {
  	x = spill_stack_slot[from_reg];
+  	}
        /* Allocate a bigger slot.  */
        else
  	{
***************
*** 2383,2400 ****
  	  /* Make a slot with that size.  */
  	  x = assign_stack_local (mode, total_size, -1);
  	  stack_slot = x;
  	  if (BYTES_BIG_ENDIAN)
  	    {
  	      /* Cancel the  big-endian correction done in assign_stack_local.
! 		 Get the address of the beginning of the slot.
! 		 This is so we can do a big-endian correction unconditionally
! 		 below.  */
  	      adjust = GET_MODE_SIZE (mode) - total_size;
! 	      if (adjust)
! 		stack_slot = gen_rtx (MEM, mode_for_size (total_size
! 							  * BITS_PER_UNIT,
! 							  MODE_INT, 1),
! 				      plus_constant (XEXP (x, 0), adjust));
  	    }
  	  spill_stack_slot[from_reg] = stack_slot;
  	  spill_stack_slot_width[from_reg] = total_size;
--- 2476,2496 ----
  	  /* Make a slot with that size.  */
  	  x = assign_stack_local (mode, total_size, -1);
  	  stack_slot = x;
+ 	  /* intel1 */
+ 	  RTX_IS_SPILL_P (x) = 1;
+ 	  RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  	  if (BYTES_BIG_ENDIAN)
  	    {
  	      /* Cancel the  big-endian correction done in assign_stack_local.
! 	         Get the address of the beginning of the slot.
! 	         This is so we can do a big-endian correction unconditionally
! 	         below.  */
  	      adjust = GET_MODE_SIZE (mode) - total_size;
! 	      if(adjust)
! 	        stack_slot = gen_rtx (MEM, mode_for_size (total_size
! 	                         * BITS_PER_UNIT,
! 	                         MODE_INT, 1),
! 	                         plus_constant (XEXP (x, 0), adjust));
  	    }
  	  spill_stack_slot[from_reg] = stack_slot;
  	  spill_stack_slot_width[from_reg] = total_size;
***************
*** 2412,2417 ****
--- 2508,2516 ----
  	  x = gen_rtx (MEM, GET_MODE (regno_reg_rtx[i]),
  		       plus_constant (XEXP (x, 0), adjust));
  	  RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]);
+ 	  /* intel1 */
+ 	  RTX_IS_SPILL_P (x) = 1;
+ 	  RTX_IS_SPILL_P (XEXP (x, 0)) = 1;
  	}
  
        /* Save the stack slot for later.   */
***************
*** 2650,2655 ****
--- 2749,2756 ----
    int i, j;
    char *fmt;
    int copied = 0;
+   /* intel1 */
+   int indx;
  
    switch (code)
      {
***************
*** 2699,2704 ****
--- 2800,2823 ----
  	     address in case it is shared.  */
  	  new = eliminate_regs (reg_equiv_memory_loc[regno],
  				mem_mode, insn);
+ 	  /* intel1 */
+ 	  if ((flag_loop_after_global || flag_peep_spills)
+ 	      && treplace_insn && is_a_stack_slot (new) 
+ 	      && !is_a_reload_stack_slot (new, &indx, cur_stack_offset, treplace_insn)
+ 	      && num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS)
+ 	    {
+               if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS)
+                 {
+ 	          reload_slots[num_reload_stack_slots].cur_stack_offset 
+ 	            = cur_stack_offset;
+ 	          reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg 
+ 		    = regno;
+ 	          reload_slots[num_reload_stack_slots].reload_stack_slot 
+ 		    = new;
+ 	          reload_slots[num_reload_stack_slots++].reload_insn
+ 		    = treplace_insn;
+ 		}
+ 	    }
  	  if (new != reg_equiv_memory_loc[regno])
  	    {
  	      cannot_omit_stores[regno] = 1;
***************
*** 3094,3103 ****
--- 3213,3226 ----
        new = eliminate_regs (XEXP (x, 0), GET_MODE (x), insn);
        if (new != XEXP (x, 0))
  	{
+ 	  /* intel1 */
+ 	  new->is_spill_rtx = x->is_spill_rtx;
  	  new = gen_rtx (MEM, GET_MODE (x), new);
  	  new->volatil = x->volatil;
  	  new->unchanging = x->unchanging;
  	  new->in_struct = x->in_struct;
+ 	  /* intel1 */
+ 	  new->is_spill_rtx = x->is_spill_rtx;
  	  return new;
  	}
        else
***************
*** 3236,3242 ****
  	       will delete it in reload_as_needed once we know that this
  	       elimination is, in fact, being done.
  
! 	       If REPLACE isn't set, we can't delete this insn, but needn't
  	       process it since it won't be used unless something changes.  */
  	    if (replace)
  	      delete_dead_insn (insn);
--- 3359,3365 ----
  	       will delete it in reload_as_needed once we know that this
  	       elimination is, in fact, being done.
  
! 	       If REPLACE isn't set, we can't delete this insn, but neededn't
  	       process it since it won't be used unless something changes.  */
  	    if (replace)
  	      delete_dead_insn (insn);
***************
*** 3288,3295 ****
--- 3411,3422 ----
       re-recognize the insn.  We do this in case we had a simple addition
       but now can do this as a load-address.  This saves an insn in this
       common case. */
+   /* intel1 */
+   treplace_insn = replace ? insn : NULL_RTX;
  
    new_body = eliminate_regs (old_body, 0, replace ? insn : NULL_RTX);
+   /* intel1 */
+   treplace_insn = NULL_RTX;
    if (new_body != old_body)
      {
        /* If we aren't replacing things permanently and we changed something,
***************
*** 3806,3812 ****
  	{
  	  rtx avoid_return_reg = 0;
  	  rtx oldpat = PATTERN (insn);
- 
  #ifdef SMALL_REGISTER_CLASSES
  	  /* Set avoid_return_reg if this is an insn
  	     that might use the value of a function call.  */
--- 3933,3938 ----
***************
*** 3961,3966 ****
--- 4087,4102 ----
  		  forget_old_reloads_1 (XEXP (x, 0), NULL_RTX);
  	      }
  #endif
+           /* intel1 */
+ 	  if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ 	    {
+ 	      int i;
+ 	      for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
+ 		update_stack_offset (XVECEXP (PATTERN (insn), 0, i), 
+ 		                     &cur_stack_offset);
+ 	    }
+ 	  else
+ 	    update_stack_offset (PATTERN (insn), &cur_stack_offset);
  	}
        /* A reload reg's contents are unknown after a label.  */
        if (GET_CODE (insn) == CODE_LABEL)
***************
*** 5650,5661 ****
    rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
    rtx operand_reload_insns = 0;
    rtx other_operand_reload_insns = 0;
-   rtx other_output_reload_insns = 0;
    rtx following_insn = NEXT_INSN (insn);
    rtx before_insn = insn;
    int special;
    /* Values to be put in spill_reg_store are put here first.  */
    rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
  
    for (j = 0; j < reload_n_operands; j++)
      input_reload_insns[j] = input_address_reload_insns[j]
--- 5786,5798 ----
    rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
    rtx operand_reload_insns = 0;
    rtx other_operand_reload_insns = 0;
    rtx following_insn = NEXT_INSN (insn);
    rtx before_insn = insn;
    int special;
    /* Values to be put in spill_reg_store are put here first.  */
    rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
+   int indx; /* intel1 */
+   rtx tmp_stack_slot, reload_insn; /* intel1 */
  
    for (j = 0; j < reload_n_operands; j++)
      input_reload_insns[j] = input_address_reload_insns[j]
***************
*** 6054,6062 ****
  					   third_reload_reg)));
  			    }
  			  else
  			    gen_reload (second_reload_reg, oldequiv,
  					reload_opnum[j],
! 					reload_when_needed[j]);
  
  			  oldequiv = second_reload_reg;
  			}
--- 6191,6231 ----
  					   third_reload_reg)));
  			    }
  			  else
+               /* intel1 */
+               reload_insn =
  			    gen_reload (second_reload_reg, oldequiv,
  					reload_opnum[j],
! 			reload_when_needed[j]);
!              /* intel1 */
!              if ((flag_loop_after_global ||flag_peep_spills) 
!                &&is_a_reload_stack_slot(oldequiv,&indx,cur_stack_offset,NULL))
!               {
!                  RTX_IS_SPILL_P (reload_insn) = 1;
!                  if (indx == -1)
!                  {
!                     tmp_stack_slot
!                      = eliminate_regs (
!                      reg_equiv_memory_loc[REGNO (oldequiv)],
!                      GET_MODE (oldequiv), NULL_RTX);
! 
!                      if (num_reload_stack_slots < MAX_RELOAD_ STACK_SLOTS
!                      && !is_a_reload_stack_slot (tmp_stack_slot, &indx, cur_stack_offset, NULL))
!                      {
!                         reload_slots[num_reload_stack_slots].cur_stack_offset
!                            = cur_stack_offset;
!                       reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
!                            = REGNO (oldequiv);
!                           reload_slots[num_reload_stack_slots].reload_stack_slot
!                            = tmp_stack_slot;
!                            reload_slots[num_reload_stack_slots++].reload_insn
!                            = NULL;
!                       }
!                          SPILL_PSEUDO (reload_insn) = REGNO (oldequiv);
!                     }
!                      else
!                         SPILL_PSEUDO (reload_insn)
!                          = reload_slots[indx].stack_slot_pseudo_reg;
!                   }
  
  			  oldequiv = second_reload_reg;
  			}
***************
*** 6065,6072 ****
  #endif
  
  	      if (! special && ! rtx_equal_p (reloadreg, oldequiv))
! 		gen_reload (reloadreg, oldequiv, reload_opnum[j],
  			    reload_when_needed[j]);
  
  #if defined(SECONDARY_INPUT_RELOAD_CLASS) && defined(PRESERVE_DEATH_INFO_REGNO_P)
  	      /* We may have to make a REG_DEAD note for the secondary reload
--- 6234,6271 ----
  #endif
  
  	      if (! special && ! rtx_equal_p (reloadreg, oldequiv))
! 		  /* intel1 */
! 		reload_insn = gen_reload (reloadreg, oldequiv, reload_opnum[j],
  			    reload_when_needed[j]);
+       /* intel1 */ if ((flag_loop_after_global || flag_peep_spills)
+            && is_a_reload_stack_slot (oldequiv, &indx, cur_stack_offset, NULL))
+           {
+            RTX_IS_SPILL_P (reload_insn) = 1;
+            if (indx == -1)
+              {
+                tmp_stack_slot
+                  = eliminate_regs (
+                  reg_equiv_memory_loc[REGNO (oldequiv)],
+                  GET_MODE (oldequiv), NULL_RTX);
+ 
+                   if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS
+                      && !is_a_reload_stack_slot (tmp_stack_slot, &indx, cur_stack_offset, NULL))
+                   {
+                      reload_slots[num_reload_stack_slots].cur_stack_offset
+                       = cur_stack_offset;
+                      reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
+                       = REGNO (oldequiv);
+                        reload_slots[num_reload_stack_slots].reload_stack_slot 
+                       = tmp_stack_slot;
+                         reload_slots[num_reload_stack_slots++].reload_insn
+                       = NULL;
+                   }
+                     SPILL_PSEUDO (reload_insn) = REGNO (oldequiv);
+               }
+             else
+               SPILL_PSEUDO (reload_insn)
+                 = reload_slots[indx].stack_slot_pseudo_reg;
+           }
  
  #if defined(SECONDARY_INPUT_RELOAD_CLASS) && defined(PRESERVE_DEATH_INFO_REGNO_P)
  	      /* We may have to make a REG_DEAD note for the secondary reload
***************
*** 6260,6275 ****
  	      XEXP (note, 0) = reload_reg_rtx[j];
  	      continue;
  	    }
- 	  /* Likewise for a SUBREG of an operand that dies.  */
- 	  else if (GET_CODE (old) == SUBREG
- 		   && GET_CODE (SUBREG_REG (old)) == REG
- 		   && 0 != (note = find_reg_note (insn, REG_UNUSED,
- 						  SUBREG_REG (old))))
- 	    {
- 	      XEXP (note, 0) = gen_lowpart_common (GET_MODE (old),
- 						   reload_reg_rtx[j]);
- 	      continue;
- 	    }
  	  else if (GET_CODE (old) == SCRATCH)
  	    /* If we aren't optimizing, there won't be a REG_UNUSED note,
  	       but we don't want to make an output reload.  */
--- 6459,6464 ----
***************
*** 6289,6298 ****
  	  if (GET_CODE (insn) == JUMP_INSN)
  	    abort ();
  
! 	  if (reload_when_needed[j] == RELOAD_OTHER)
! 	    start_sequence ();
! 	  else
! 	    push_to_sequence (output_reload_insns[reload_opnum[j]]);
  
  	  /* Determine the mode to reload in.
  	     See comments above (for input reloading).  */
--- 6478,6484 ----
  	  if (GET_CODE (insn) == JUMP_INSN)
  	    abort ();
  
! 	  push_to_sequence (output_reload_insns[reload_opnum[j]]);
  
  	  /* Determine the mode to reload in.
  	     See comments above (for input reloading).  */
***************
*** 6358,6380 ****
  			{
  			  rtx third_reloadreg
  			    = reload_reg_rtx[reload_secondary_out_reload[secondary_reload]];
- 			  rtx tem;
  
  			  /* Copy primary reload reg to secondary reload reg.
  			     (Note that these have been swapped above, then
  			     secondary reload reg to OLD using our insn.  */
  
- 			  /* If REAL_OLD is a paradoxical SUBREG, remove it
- 			     and try to put the opposite SUBREG on
- 			     RELOADREG.  */
- 			  if (GET_CODE (real_old) == SUBREG
- 			      && (GET_MODE_SIZE (GET_MODE (real_old))
- 				  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (real_old))))
- 			      && 0 != (tem = gen_lowpart_common
- 				       (GET_MODE (SUBREG_REG (real_old)),
- 					reloadreg)))
- 			    real_old = SUBREG_REG (real_old), reloadreg = tem;
- 
  			  gen_reload (reloadreg, second_reloadreg,
  				      reload_opnum[j], reload_when_needed[j]);
  			  emit_insn ((GEN_FCN (tertiary_icode)
--- 6544,6554 ----
***************
*** 6392,6402 ****
--- 6566,6612 ----
  		}
  	    }
  #endif
+ 	/* PROBLEM: supposed to be intel code here, but too much has
+ 	  changed above, I don't know how it maps */
  
  	  /* Output the last reload insn.  */
  	  if (! special)
+ /*
  	    gen_reload (old, reloadreg, reload_opnum[j],
  			reload_when_needed[j]);
+ */
+ 		{
+ 			emit_insn(gen_move_insn(old,reloadreg));
+  /* intel1 */ if ((flag_loop_after_global || flag_peep_spills)
+               && is_a_reload_stack_slot (old, &indx, cur_stack_offset, NULL))
+               {
+                   reload_insn = get_last_insn ();
+                   RTX_IS_SPILL_P ( reload_insn) = 1;
+                   if (indx == -1)
+                   {
+                      tmp_stack_slot = eliminate_regs (
+                             reg_equiv_memory_loc[REGNO (old)],
+                             GET_MODE (old), NULL_RTX);
+ 
+                     if (num_reload_stack_slots < MAX_RELOAD_STACK_SLOTS
+                        && !is_a_reload_stack_slot (tmp_stack_slot, &indx,
+ 						 cur_stack_offset, NULL))
+                     {
+                       reload_slots[num_reload_stack_slots].cur_stack_offset
+                                 = cur_stack_offset;
+                       reload_slots[num_reload_stack_slots].stack_slot_pseudo_reg
+                                 = REGNO (old);
+                       reload_slots[num_reload_stack_slots].reload_stack_slot
+                                 = tmp_stack_slot;
+                       reload_slots[num_reload_stack_slots++].reload_insn = NULL;
+                     }
+                   SPILL_PSEUDO (reload_insn) = REGNO (old);
+                  } else
+                     SPILL_PSEUDO (reload_insn)
+                          = reload_slots[indx].stack_slot_pseudo_reg;
+                }
+             }
+ 
  
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
  	  /* If final will look at death notes for this reg,
***************
*** 6436,6450 ****
  		  new_spill_reg_store[reload_spill_index[j]] = p;
  	      }
  
! 	  if (reload_when_needed[j] == RELOAD_OTHER)
! 	    {
! 	      if (other_output_reload_insns)
! 		emit_insns (other_output_reload_insns);
! 	      other_output_reload_insns = get_insns ();
! 	    }
! 	  else
! 	    output_reload_insns[reload_opnum[j]] = get_insns ();
! 
  	  end_sequence ();
  	}
      }
--- 6646,6652 ----
  		  new_spill_reg_store[reload_spill_index[j]] = p;
  	      }
  
! 	  output_reload_insns[reload_opnum[j]] = get_insns ();
  	  end_sequence ();
  	}
      }
***************
*** 6455,6461 ****
  
       RELOAD_FOR_OTHER_ADDRESS reloads for input addresses.
  
!      RELOAD_OTHER reloads, output in ascending order by reload number.
  
       For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by
       the RELOAD_FOR_INPUT reload for the operand.
--- 6657,6663 ----
  
       RELOAD_FOR_OTHER_ADDRESS reloads for input addresses.
  
!      RELOAD_OTHER reloads.
  
       For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by
       the RELOAD_FOR_INPUT reload for the operand.
***************
*** 6467,6476 ****
       After the insn being reloaded, we write the following:
  
       For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by
!      the RELOAD_FOR_OUTPUT reload for that operand.
! 
!      Any RELOAD_OTHER output reloads, output in descending order by
!      reload number.  */
  
    emit_insns_before (other_input_address_reload_insns, before_insn);
    emit_insns_before (other_input_reload_insns, before_insn);
--- 6669,6675 ----
       After the insn being reloaded, we write the following:
  
       For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by
!      the RELOAD_FOR_OUTPUT reload for that operand.  */
  
    emit_insns_before (other_input_address_reload_insns, before_insn);
    emit_insns_before (other_input_reload_insns, before_insn);
***************
*** 6490,6497 ****
        emit_insns_before (output_reload_insns[j], following_insn);
      }
  
-   emit_insns_before (other_output_reload_insns, following_insn);
- 
    /* Move death notes from INSN
       to output-operand-address and output reload insns.  */
  #ifdef PRESERVE_DEATH_INFO_REGNO_P
--- 6689,6694 ----
***************
*** 6691,6696 ****
--- 6888,6895 ----
       int opnum;
       enum reload_type type;
  {
+   /* intel1 */
+   int indx;
    rtx last = get_last_insn ();
    rtx tem;
  
***************
*** 6858,6864 ****
--- 7057,7080 ----
  
    /* If IN is a simple operand, use gen_move_insn.  */
    else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG)
+   {
      emit_insn (gen_move_insn (out, in));
+     if ((flag_loop_after_global || flag_peep_spills)   /* intel1 */
+       && is_a_reload_stack_slot (in, &indx, cur_stack_offset, get_last_insn()))
+       {
+         rtx reload_insn = get_last_insn ();
+ 
+   RTX_IS_SPILL_P ( reload_insn) = 1;
+   if (indx == -1)
+      {
+            SPILL_PSEUDO (reload_insn) = REGNO (in);
+      }
+   else
+      SPILL_PSEUDO (reload_insn)
+         = reload_slots[indx].stack_slot_pseudo_reg;
+       }
+   }
+ 
  
  #ifdef HAVE_reload_load_address
    else if (HAVE_reload_load_address)
***************
*** 7173,7176 ****
--- 7389,7643 ----
  	}
      }
    return count;
+ }
+ 
+ /* intel1 */
+ 
+ /* return 1 if rx is a stack slot */
+ int
+ is_a_stack_slot (rx)
+   rtx rx;
+ {
+  if (GET_CODE (rx) != MEM)
+     {
+       return (0);
+     }
+   if (GET_CODE (XEXP (rx, 0)) == PLUS 
+       && XEXP ( XEXP (rx, 0), 0) == stack_pointer_rtx 
+       && !frame_pointer_needed)
+     {
+       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
+         {
+           return (1);
+         }
+       else
+         {
+           return (0);
+         }
+     }
+   else if (GET_CODE (XEXP (rx, 0)) == PLUS 
+       && XEXP ( XEXP (rx, 0), 0) == frame_pointer_rtx
+       && frame_pointer_needed)
+     {
+       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
+         {
+           return (1);
+         }
+       else
+         {
+           return (0);
+         }
+     }
+   else if ((XEXP (rx, 0) == frame_pointer_rtx  && frame_pointer_needed)
+            || (XEXP (rx, 0) == stack_pointer_rtx && ! frame_pointer_needed))
+     {
+       return (1);
+     }
+   else
+     {
+       return (0);
+     }
+    
+ }
+ 
+ /*
+   if rx is a reload slot then set *indx to the index in the
+     reload_slots array which contains it and return 1
+   else
+     return 0
+ */
+ 
+ int
+ is_a_reload_stack_slot (rx, indx, cur_stack_offset, reload_insn)
+      rtx rx;
+      int *indx;
+      int cur_stack_offset;
+      rtx reload_insn;
+ {
+   int i, is_based_on_stack_pointer, stack_offset, stack_i_offset;
+   rtx stack_slot_i;
+ 
+   
+   if (GET_CODE (rx) == REG && REGNO (rx) >= FIRST_PSEUDO_REGISTER
+       && pseudo_spilled[REGNO (rx)])
+     {
+       *indx = -1;
+       return (1);
+     }
+   if (GET_CODE (rx) == SUBREG 
+       && GET_CODE (SUBREG_REG (rx)) == MEM)
+     {
+       return (is_a_reload_stack_slot (SUBREG_REG (rx), indx, 
+                                       cur_stack_offset, reload_insn));
+     }
+   if (GET_CODE (rx) != MEM)
+     {
+       return (0);
+     }
+   is_based_on_stack_pointer = 0;
+   if (GET_CODE (XEXP (rx, 0)) == PLUS 
+       && XEXP ( XEXP (rx, 0), 0) == stack_pointer_rtx 
+       && !frame_pointer_needed)
+     {
+       is_based_on_stack_pointer = 1;
+       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
+         {
+           stack_offset = XINT (XEXP ( XEXP (rx, 0), 1), 0);
+         }
+       else
+         {
+           return (0);
+         }
+     }
+   else if (GET_CODE (XEXP (rx, 0)) == PLUS 
+       && XEXP ( XEXP (rx, 0), 0) == frame_pointer_rtx
+       && frame_pointer_needed)
+     {
+       if ( GET_CODE (XEXP ( XEXP (rx, 0), 1)) == CONST_INT)
+         {
+           ;
+         }
+       else
+         {
+           return (0);
+         }
+     }
+   else if ((XEXP (rx, 0) == frame_pointer_rtx  && frame_pointer_needed)
+            || (XEXP (rx, 0) == stack_pointer_rtx && ! frame_pointer_needed))
+     {
+       is_based_on_stack_pointer = (XEXP (rx, 0) == stack_pointer_rtx );
+     }
+   else
+     {
+       return (0);
+     }
+            
+ 
+   for (i = 0; i < num_reload_stack_slots; i++)
+     {
+       if (!is_based_on_stack_pointer)
+         {
+           if ((reload_insn == NULL || reload_insn == reload_slots[i].reload_insn)
+               && rtx_equal_p (XEXP (reload_slots[i].reload_stack_slot, 0), 
+                            XEXP (rx, 0)))
+ 	    {
+ 	      *indx = i;
+ 	      return (1);
+ 	    }
+ 	}
+       else
+         {
+           stack_slot_i = XEXP (reload_slots[i].reload_stack_slot, 0);
+           if (GET_CODE (stack_slot_i) == PLUS 
+               && XEXP ( stack_slot_i, 0) == stack_pointer_rtx)
+             {
+               if ( GET_CODE (XEXP ( stack_slot_i, 1)) == CONST_INT)
+                 {
+                   stack_i_offset = XINT (XEXP ( stack_slot_i, 1), 0);
+                 }
+               else
+                 {
+                   abort ();
+                 }
+             }
+           else if (stack_slot_i == stack_pointer_rtx)
+             {
+               stack_i_offset = 0;
+             }
+           else
+             {
+               abort ();
+             }
+           stack_i_offset -= reload_slots[i].cur_stack_offset;
+           if ((reload_insn == NULL || reload_insn == reload_slots[i].reload_insn)
+               && (stack_offset - cur_stack_offset == stack_i_offset))
+             {
+ 	      *indx = i;
+ 	      return (1);
+             }
+         }
+     }
+   return (0);
+ }
+ 
+ 
+ int
+ are_same_reload_slots (slot1, offset1, slot2, offset2)
+   rtx slot1, slot2;
+   int offset1, offset2;
+ {
+   rtx base_reg1, base_reg2;
+   int add_val1, add_val2;
+ 
+   if (GET_CODE (XEXP (slot1, 0)) == PLUS)
+     {
+       if (GET_CODE (XEXP (XEXP (slot1, 0), 0)) == REG)
+         {
+           base_reg1 = XEXP (XEXP (slot1, 0), 0);
+           if (GET_CODE (XEXP (XEXP (slot1, 0), 1)) == CONST_INT)
+             {
+               add_val1 = XINT (XEXP (XEXP (slot1, 0), 1), 0);
+             }
+         }
+     }
+   else
+     {
+       add_val1 = 0;
+       base_reg1 = XEXP (slot1, 0);
+     }
+     
+   if (GET_CODE (XEXP (slot2, 0)) == PLUS)
+     {
+       if (GET_CODE (XEXP (XEXP (slot2, 0), 0)) == REG)
+         {
+           base_reg2 = XEXP (XEXP (slot2, 0), 0);
+           if (GET_CODE (XEXP (XEXP (slot2, 0), 1)) == CONST_INT)
+             {
+               add_val2 = XINT (XEXP (XEXP (slot2, 0), 1), 0);
+             }
+         }
+     }
+   else
+     {
+       add_val2 = 0;
+       base_reg2 = XEXP (slot2, 0);
+     }
+   if (base_reg1 == frame_pointer_rtx)
+     {
+       offset1 = 0;
+     }
+   if (base_reg2 == frame_pointer_rtx)
+     {
+       offset2 = 0;
+     }
+   if (base_reg1 == base_reg2 
+       && ((add_val1 - offset1) == (add_val2 - offset2)))
+     {
+       return (1);
+     }
+   return (0);
+ }
+ 
+ /*
+   if x refernces a paramater then return 1
+   else return 0
+ */
+ 
+ int 
+ is_a_param_slot (x)
+      rtx x;
+ {
+   if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PLUS
+       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+       && REGNO (XEXP (XEXP (x, 0), 0)) == ARG_POINTER_REGNUM
+       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+     {
+       return (1);
+     }
+   if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == REG
+       && REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM)
+     {
+       return (1);
+     }
+   return (0);
  }
diff -rNci gcc-2.7.2/reorg.c gcc-2.7.2p/reorg.c
*** gcc-2.7.2/reorg.c	Fri Sep 15 21:38:55 1995
--- gcc-2.7.2p/reorg.c	Thu Jun 15 12:02:32 1995
***************
*** 2857,2880 ****
  	  && eligible_for_delay (insn, slots_filled, trial, flags)
  	  && no_labels_between_p (insn, trial))
  	{
- 	  rtx *tmp;
  	  slots_filled++;
  	  delay_list = add_to_delay_list (trial, delay_list);
- 
- 	  /* TRIAL may have had its delay slot filled, then unfilled.  When
- 	     the delay slot is unfilled, TRIAL is placed back on the unfilled
- 	     slots obstack.  Unfortunately, it is placed on the end of the
- 	     obstack, not in its original location.  Therefore, we must search
- 	     from entry i + 1 to the end of the unfilled slots obstack to
- 	     try and find TRIAL.  */
- 	  tmp = &unfilled_slots_base[i + 1];
- 	  while (*tmp != trial && tmp != unfilled_slots_next)
- 	    tmp++;
- 
  	  /* Remove the unconditional jump from consideration for delay slot
! 	     filling and unthread it.   */
! 	  if (*tmp == trial)
! 	    *tmp = 0;
  	  {
  	    rtx next = NEXT_INSN (trial);
  	    rtx prev = PREV_INSN (trial);
--- 2857,2868 ----
  	  && eligible_for_delay (insn, slots_filled, trial, flags)
  	  && no_labels_between_p (insn, trial))
  	{
  	  slots_filled++;
  	  delay_list = add_to_delay_list (trial, delay_list);
  	  /* Remove the unconditional jump from consideration for delay slot
! 	     filling and unthread it.  */
! 	  if (unfilled_slots_base[i + 1] == trial)
! 	    unfilled_slots_base[i + 1] = 0;
  	  {
  	    rtx next = NEXT_INSN (trial);
  	    rtx prev = PREV_INSN (trial);
***************
*** 2974,2985 ****
  	 is a CALL_INSN (or a CALL_INSN is passed), cannot trap (because the
  	 call might not return).
  
! 	 There used to be code which continued past the target label if
! 	 we saw all uses of the target label.  This code did not work,
! 	 because it failed to account for some instructions which were
! 	 both annulled and marked as from the target.  This can happen as a
! 	 result of optimize_skip.  Since this code was redundant with
! 	 fill_eager_delay_slots anyways, it was just deleted.  */
  
        if (slots_filled != slots_to_fill
            && (GET_CODE (insn) != JUMP_INSN
--- 2962,2975 ----
  	 is a CALL_INSN (or a CALL_INSN is passed), cannot trap (because the
  	 call might not return).
  
! 	 If this is a conditional jump, see if it merges back to us early
! 	 enough for us to pick up insns from the merge point.  Don't do
! 	 this if there is another branch to our label unless we pass all of
! 	 them.
! 
! 	 Another similar merge is if we jump to the same place that a
! 	 later unconditional jump branches to.  In that case, we don't
! 	 care about the number of uses of our label.  */
  
        if (slots_filled != slots_to_fill
            && (GET_CODE (insn) != JUMP_INSN
***************
*** 2989,2994 ****
--- 2979,2986 ----
  	{
  	  rtx target = 0;
  	  int maybe_never = 0;
+ 	  int passed_label = 0;
+ 	  int target_uses;
  	  struct resources needed_at_jump;
  
  	  CLEAR_RESOURCE (&needed);
***************
*** 3005,3011 ****
  	      mark_set_resources (insn, &set, 0, 1);
  	      mark_referenced_resources (insn, &needed, 1);
  	      if (GET_CODE (insn) == JUMP_INSN)
! 		target = JUMP_LABEL (insn);
  	    }
  
  	  for (trial = next_nonnote_insn (insn); trial; trial = next_trial)
--- 2997,3009 ----
  	      mark_set_resources (insn, &set, 0, 1);
  	      mark_referenced_resources (insn, &needed, 1);
  	      if (GET_CODE (insn) == JUMP_INSN)
! 		{
! 		  /* Get our target and show how many more uses we want to
! 		     see before we hit the label.  */
! 		  target = JUMP_LABEL (insn);
! 		  target_uses = LABEL_NUSES (target) - 1;
! 		}
! 		
  	    }
  
  	  for (trial = next_nonnote_insn (insn); trial; trial = next_trial)
***************
*** 3014,3021 ****
  
  	      next_trial = next_nonnote_insn (trial);
  
! 	      if (GET_CODE (trial) == CODE_LABEL
! 		  || GET_CODE (trial) == BARRIER)
  		break;
  
  	      /* We must have an INSN, JUMP_INSN, or CALL_INSN.  */
--- 3012,3033 ----
  
  	      next_trial = next_nonnote_insn (trial);
  
! 	      if (GET_CODE (trial) == CODE_LABEL)
! 		{
! 		  passed_label = 1;
! 
! 		  /* If this is our target, see if we have seen all its uses.
! 		     If so, indicate we have passed our target and ignore it.
! 		     All other labels cause us to stop our search.  */
! 		  if (trial == target && target_uses == 0)
! 		    {
! 		      target = 0;
! 		      continue;
! 		    }
! 		  else
! 		    break;
! 		}
! 	      else if (GET_CODE (trial) == BARRIER)
  		break;
  
  	      /* We must have an INSN, JUMP_INSN, or CALL_INSN.  */
***************
*** 3040,3046 ****
  		{
  		  if (target == 0)
  		    break;
! 		  else if (JUMP_LABEL (trial_delay) != target)
  		    {
  		      mark_target_live_regs
  			(next_active_insn (JUMP_LABEL (trial_delay)),
--- 3052,3060 ----
  		{
  		  if (target == 0)
  		    break;
! 		  else if (JUMP_LABEL (trial_delay) == target)
! 		    target_uses--;
! 		  else
  		    {
  		      mark_target_live_regs
  			(next_active_insn (JUMP_LABEL (trial_delay)),
***************
*** 3073,3078 ****
--- 3087,3094 ----
  		    link_cc0_insns (trial);
  #endif
  
+ 		  if (passed_label)
+ 		    update_block (trial, trial);
  		  delete_insn (trial);
  		  if (slots_to_fill == ++slots_filled)
  		    break;
***************
*** 3398,3405 ****
  	      trial = try_split (pat, trial, 0);
  	      if (new_thread == old_trial)
  		new_thread = trial;
- 	      if (thread == old_trial)
- 		thread = trial;
  	      pat = PATTERN (trial);
  	      if ((thread_if_true
  		   ? eligible_for_annul_false (insn, *pslots_filled, trial, flags)
--- 3414,3419 ----
***************
*** 3663,3669 ****
        if (condition == 0)
  	continue;
  
!       /* Get the next active fallthrough and target insns and see if we own
  	 them.  Then see whether the branch is likely true.  We don't need
  	 to do a lot of this for unconditional branches.  */
  
--- 3677,3683 ----
        if (condition == 0)
  	continue;
  
!       /* Get the next active fallthough and target insns and see if we own
  	 them.  Then see whether the branch is likely true.  We don't need
  	 to do a lot of this for unconditional branches.  */
  
diff -rNci gcc-2.7.2/rtl.c gcc-2.7.2p/rtl.c
*** gcc-2.7.2/rtl.c	Thu Jun 15 12:02:59 1995
--- gcc-2.7.2p/rtl.c	Tue Jan 23 09:25:31 1996
***************
*** 174,184 ****
  			   "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
  			   "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
  
  char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  			  "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
  			  "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
! 			  "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
  
  /* Allocate an rtx vector of N elements.
     Store the length, and initialize all elements to zero.  */
--- 174,185 ----
  			   "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
  			   "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
  
+ /* intel1 added REG_DEP_TMP */
  char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
  			  "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
  			  "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
  			  "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
! 			  "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_DEP_TMP"  };
  
  /* Allocate an rtx vector of N elements.
     Store the length, and initialize all elements to zero.  */
***************
*** 302,307 ****
--- 303,310 ----
    copy->volatil = orig->volatil;
    copy->unchanging = orig->unchanging;
    copy->integrated = orig->integrated;
+   /* intel1 */
+   copy->is_spill_rtx = orig->is_spill_rtx;
    
    format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
  
diff -rNci gcc-2.7.2/rtl.def gcc-2.7.2p/rtl.def
*** gcc-2.7.2/rtl.def	Thu Jun 15 12:03:32 1995
--- gcc-2.7.2p/rtl.def	Tue Jan 23 09:25:31 1996
***************
*** 347,353 ****
     ---------------------------------------------------------------------- */
  
  /* An instruction that cannot jump.  */
! DEF_RTL_EXPR(INSN, "insn", "iuueiee", 'i')
  
  /* An instruction that can possibly jump.
     Fields ( rtx->fld[] ) have exact same meaning as INSN's.  */
--- 347,354 ----
     ---------------------------------------------------------------------- */
  
  /* An instruction that cannot jump.  */
! /* intel1 added last 0 - this field is used in scheduling */
! DEF_RTL_EXPR(INSN, "insn", "iuueiee0", 'i')
  
  /* An instruction that can possibly jump.
     Fields ( rtx->fld[] ) have exact same meaning as INSN's.  */
***************
*** 644,650 ****
  
  /* Operand:
       0:  value to be shifted.
!      1:  number of bits.  */
  DEF_RTL_EXPR(ASHIFT, "ashift", "ee", '2')
  DEF_RTL_EXPR(ROTATE, "rotate", "ee", '2')
  
--- 645,655 ----
  
  /* Operand:
       0:  value to be shifted.
!      1:  number of bits.  
!    ASHIFT and LSHIFT are distinguished because on some machines
!    these allow a negative operand and shift right in that case.
! */
! DEF_RTL_EXPR(LSHIFT, "lshift", "ee", '2')
  DEF_RTL_EXPR(ASHIFT, "ashift", "ee", '2')
  DEF_RTL_EXPR(ROTATE, "rotate", "ee", '2')
  
diff -rNci gcc-2.7.2/rtl.h gcc-2.7.2p/rtl.h
*** gcc-2.7.2/rtl.h	Thu Jun 15 12:03:16 1995
--- gcc-2.7.2p/rtl.h	Tue Jan 23 09:25:31 1996
***************
*** 140,145 ****
--- 140,148 ----
       In a REG, nonzero means this reg refers to the return value
       of the current function.  */
    unsigned integrated : 1;
+   /* intel1 Nonzero if this rtx is a spill rtx */
+   /* intel2 overlap: Nonzero if this rtx was created by memory_simplify */
+   unsigned is_spill_rtx: 1;
    /* The first element of the operands of this rtx.
       The number of operands and their types are controlled
       by the `code' field, according to rtl.def.  */
***************
*** 211,216 ****
--- 214,223 ----
  
  #define RTX_INTEGRATED_P(RTX) ((RTX)->integrated)
  #define RTX_UNCHANGING_P(RTX) ((RTX)->unchanging)
+ /* intel1 */
+ #define RTX_IS_SPILL_P(RTX) ((RTX)->is_spill_rtx)
+ /* intel2 - see a note above (for is_spill_rtx field) */
+ #define RTX_IS_RISC_P(RTX) ((RTX)->is_spill_rtx)
  
  /* RTL vector.  These appear inside RTX's when there is a need
     for a variable number of things.  The principle use is inside
***************
*** 259,264 ****
--- 266,276 ----
  #define PREV_INSN(INSN)	((INSN)->fld[1].rtx)
  #define NEXT_INSN(INSN)	((INSN)->fld[2].rtx)
  
+ /* intel1 used in sched*/
+ #define ORG_NEXT_INSN(INSN)	((INSN)->fld[7].rtx)
+ /* intel1 used in (loop) opt of spills */
+ #define SPILL_PSEUDO(INSN)	((INSN)->fld[7].rtint)
+ 
  /* The body of an insn.  */
  #define PATTERN(INSN)	((INSN)->fld[3].rtx)
  
***************
*** 348,354 ****
  		REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
  		REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
  		REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
! 		REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 };
  
  /* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
  #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
--- 360,366 ----
  		REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
  		REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
  		REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
! 		REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_DEP_TMP = 16 };
  
  /* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
  #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
diff -rNci gcc-2.7.2/rtlanal.c gcc-2.7.2p/rtlanal.c
*** gcc-2.7.2/rtlanal.c	Fri Oct  6 17:13:57 1995
--- gcc-2.7.2p/rtlanal.c	Thu Jun 15 12:03:58 1995
***************
*** 428,435 ****
  static rtx reg_set_reg;
  static int reg_set_flag;
  
! static void
! reg_set_p_1 (x, pat)
       rtx x;
  {
    /* We don't want to return 1 if X is a MEM that contains a register
--- 428,435 ----
  static rtx reg_set_reg;
  static int reg_set_flag;
  
! void
! reg_set_p_1 (x)
       rtx x;
  {
    /* We don't want to return 1 if X is a MEM that contains a register
***************
*** 905,911 ****
  		|| ((GET_CODE (reg_set_last_value) == REG
  		     || GET_CODE (reg_set_last_value) == SUBREG)
  		    && ! reg_set_between_p (reg_set_last_value,
! 					    insn, orig_insn)))
  	      return reg_set_last_value;
  	    else
  	      return 0;
--- 905,911 ----
  		|| ((GET_CODE (reg_set_last_value) == REG
  		     || GET_CODE (reg_set_last_value) == SUBREG)
  		    && ! reg_set_between_p (reg_set_last_value,
! 					    NEXT_INSN (insn), orig_insn)))
  	      return reg_set_last_value;
  	    else
  	      return 0;
diff -rNci gcc-2.7.2/scan-decls.c gcc-2.7.2p/scan-decls.c
*** gcc-2.7.2/scan-decls.c	Mon Jun 19 18:18:43 1995
--- gcc-2.7.2p/scan-decls.c	Thu Jun 15 12:04:57 1995
***************
*** 246,252 ****
  	  break;
  
  	 default:
! 	  prev_id_start = 0;
  	}
      }
  }
--- 246,252 ----
  	  break;
  
  	 default:
! 	  prev_id_start = NULL;
  	}
      }
  }
diff -rNci gcc-2.7.2/sched.c gcc-2.7.2p/sched.c
*** gcc-2.7.2/sched.c	Thu Jun 15 12:06:39 1995
--- gcc-2.7.2p/sched.c	Tue Jan 30 21:06:34 1996
***************
*** 125,131 ****
--- 125,153 ----
  #include "insn-config.h"
  #include "insn-attr.h"
  
+ /* intel1 */
+ #ifndef STACK_PUSH_CODE
+ #ifdef STACK_GROWS_DOWNWARD
+ #define STACK_PUSH_CODE PRE_DEC
+ #else
+ #define STACK_PUSH_CODE PRE_INC
+ #endif
+ #endif
  #ifdef INSN_SCHEDULING
+ /* intel1 */
+ #ifndef STACK_PUSH_CODE
+ #ifdef STACK_GROWS_DOWNWARD
+ #define STACK_PUSH_CODE PRE_DEC
+ #else
+ #define STACK_PUSH_CODE PRE_INC
+ #endif
+ #endif
+ #ifdef SMALL_REGISTER_CLASSES
+   /* can't move anything past a hard register */
+ static rtx first_insn_to_pivot;
+ static rtx last_hard_reg_insn;
+ #endif
+ 
  /* Arrays set up by scheduling for the same respective purposes as
     similar-named arrays set up by flow analysis.  We work with these
     arrays during the scheduling pass so we can compare values against
***************
*** 146,151 ****
--- 168,184 ----
  static regset reg_pending_sets;
  static int reg_pending_sets_all;
  
+ /* intel1 */
+ #ifdef NO_STACK_REG_REORDER
+ /* don't reorder insns that refernce stack registers */
+ static rtx prev_stack_reg_insn = NULL;
+ #endif
+ /* intel1 */
+ #ifdef STACK_REGS
+ static int maintain_order = 0;
+ #endif
+ static FILE * cur_dump_file;
+ 
  /* Vector indexed by INSN_UID giving the original ordering of the insns.  */
  static int *insn_luid;
  #define INSN_LUID(INSN) (insn_luid[INSN_UID (INSN)])
***************
*** 293,305 ****
  };
  
  /* Forward declarations.  */
  static rtx canon_rtx			PROTO((rtx));
  static int rtx_equal_for_memref_p	PROTO((rtx, rtx));
  static rtx find_symbolic_term		PROTO((rtx));
  static int memrefs_conflict_p		PROTO((int, rtx, int, rtx,
  					       HOST_WIDE_INT));
  static void add_dependence		PROTO((rtx, rtx, enum reg_note));
! static void remove_dependence		PROTO((rtx, rtx));
  static rtx find_insn_list		PROTO((rtx, rtx));
  static int insn_unit			PROTO((rtx));
  static unsigned int blockage_range	PROTO((int, rtx));
--- 326,342 ----
  };
  
  /* Forward declarations.  */
+ 
+ /* intel1 */
+ static int is_part_of_group			PROTO((rtx, rtx));
+ static int prev_insts_in_block		PROTO((int, rtx));
  static rtx canon_rtx			PROTO((rtx));
  static int rtx_equal_for_memref_p	PROTO((rtx, rtx));
  static rtx find_symbolic_term		PROTO((rtx));
  static int memrefs_conflict_p		PROTO((int, rtx, int, rtx,
  					       HOST_WIDE_INT));
  static void add_dependence		PROTO((rtx, rtx, enum reg_note));
! void remove_dependence		PROTO((rtx, rtx));
  static rtx find_insn_list		PROTO((rtx, rtx));
  static int insn_unit			PROTO((rtx));
  static unsigned int blockage_range	PROTO((int, rtx));
***************
*** 629,634 ****
--- 666,906 ----
    else
      y = canon_rtx (y);
  
+   /* intel1
+      Missing special handling of a push onto the stack.  */
+   if (reload_completed
+       &&
+       (GET_CODE (x) == STACK_PUSH_CODE
+        && XEXP (x, 0) == stack_pointer_rtx)
+       ||
+       (GET_CODE (y) == STACK_PUSH_CODE
+        && XEXP (y, 0) == stack_pointer_rtx)
+       )
+     {
+       rtx *push, *non_push;
+ 
+       if (GET_CODE (x) == STACK_PUSH_CODE
+           && XEXP (x, 0) == stack_pointer_rtx)
+         {
+           push = &x;
+           non_push = &y;
+         }
+       else
+         {
+           push = &y;
+           non_push = &x;
+         }
+       if (find_symbolic_term (*non_push) != NULL)
+         {  /* push onto stack does not conflict with global */
+           return (0);
+         }
+       if (RTX_IS_SPILL_P (*non_push))
+         { /* push onto stack does not overlap with spill slot */
+           return (0);
+         }
+       /* Check to see if the non push is a stack slot */
+       if (c == 0 && GET_CODE (*non_push) == PLUS 
+           && XEXP ( *non_push, 0) == stack_pointer_rtx 
+           && !frame_pointer_needed)
+         {
+           if ( GET_CODE (XEXP ( *non_push, 1)) == CONST_INT
+                && XINT (XEXP (*non_push, 1), 0) 
+                   > GET_MODE_SIZE (GET_MODE (*push)))
+             {
+               return (0);
+             }
+         }
+       else if (c == 0 && GET_CODE (*non_push) == PLUS 
+           && XEXP ( *non_push, 0) == frame_pointer_rtx
+           && frame_pointer_needed)
+         {
+           if ( GET_CODE (XEXP ( *non_push, 1)) == CONST_INT)
+             {
+               return (0); /* Definitely not the same as the push if
+                              frame_pointer is used.  */
+             }
+         }
+     }
+   
+   
+   /* intel1
+      Missing handling of a spill slot - can't conflict with anything
+      that is not a spill slot */
+   if (reload_completed && RTX_IS_SPILL_P (x) != RTX_IS_SPILL_P (y)
+       && !rtx_equal_p(x,y) /*just to be safe */)
+     { /* Actually some spill slots are not being marked at present -
+          but no non spill slots are ever marked.  So make sure
+          that the non spill slot does not overlap with spill slot */
+       rtx *spill, *non_spill;
+       int *spill_size, *non_spill_size, spill_offset, non_spill_offset, 
+           spill_unknown, non_spill_unknown, maybe_spill;
+       spill_unknown = 0;
+       non_spill_unknown = 0;
+       maybe_spill = 0;
+       if (RTX_IS_SPILL_P (x))
+         {
+           spill = &x;
+           spill_size = &xsize;
+           non_spill = &y;
+           non_spill_size = &ysize;
+         }
+       else
+         {
+           spill = &y;
+           spill_size = &ysize;
+           non_spill = &x;
+           non_spill_size = &xsize;
+         }
+       if (GET_CODE (*non_spill) == PLUS)
+         {
+           if (GET_CODE (XEXP (*non_spill, 1)) == CONST_INT)
+             {
+               non_spill_offset = XINT (XEXP (*non_spill, 1), 0);
+             }
+           else
+             {
+               non_spill_unknown = 1;
+             }
+           if (GET_CODE (XEXP (*non_spill, 0)) == REG
+               && ((frame_pointer_needed && XEXP (*non_spill, 0) == frame_pointer_rtx)
+                   || XEXP (*non_spill, 0) == stack_pointer_rtx))
+             {
+               maybe_spill = 1; /* It may overlap the spill slot */
+             }
+         }
+       else
+       if (GET_CODE (*non_spill) == REG
+           && ((frame_pointer_needed && *non_spill == frame_pointer_rtx)
+               || *non_spill == stack_pointer_rtx))
+         {
+           non_spill_offset = 0;
+           maybe_spill = 1;
+         }
+       if (maybe_spill == 0)
+         return (0);
+         
+       if (GET_CODE (*spill) == PLUS)
+         {
+           if (GET_CODE (XEXP (*spill, 1)) == CONST_INT)
+             {
+               spill_offset = XINT (XEXP (*spill, 1), 0);
+             }
+           else
+             {
+               spill_unknown = 1;
+             }
+           if (GET_CODE (XEXP (*spill, 0)) == REG
+               && ((frame_pointer_needed && XEXP (*spill, 0) == frame_pointer_rtx)
+                   || XEXP (*spill, 0) == stack_pointer_rtx))
+             {
+               ; /* ok */
+             }
+           else
+             {
+               spill_unknown = 1;
+             }
+         }
+       else
+       if (GET_CODE (*spill) == REG
+           && ((frame_pointer_needed && *spill == frame_pointer_rtx)
+               || *spill == stack_pointer_rtx))
+         {
+          spill_offset = 0;
+         }
+       else
+         {
+           spill_unknown = 1;
+         }
+       if (non_spill_unknown == 0  && spill_unknown == 0)
+         {
+           if (non_spill_offset < spill_offset)
+             return (!(non_spill_offset + *non_spill_size <= spill_offset));
+           else
+             return (!(spill_offset + *spill_size <= non_spill_offset));
+         } 
+     }
+   
+   /* intel1
+      Missing handling two spill slots conflict only if they overlap */
+   if (reload_completed && RTX_IS_SPILL_P (y) && RTX_IS_SPILL_P (x) 
+       && c == 0 
+       && !rtx_equal_p(y, x))
+     {
+       int x_offset, y_offset, x_unknown, y_unknown;
+       x_unknown = y_unknown = 0;
+       if (GET_CODE (x) == PLUS)
+         {
+           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+             {
+               x_offset = XINT (XEXP (x, 1), 0);
+             }
+           else
+             {
+               x_unknown = 1;
+             }
+           if (GET_CODE (XEXP (x, 0)) == REG
+               && ((frame_pointer_needed && XEXP (x, 0) == frame_pointer_rtx)
+                   || XEXP (x, 0) == stack_pointer_rtx))
+             {
+               ; /* ok */
+             }
+           else
+             {
+               x_unknown = 1;
+             }
+         }
+       else
+       if (GET_CODE (x) == REG
+           && ((frame_pointer_needed && x == frame_pointer_rtx)
+               || x == stack_pointer_rtx))
+         {
+          x_offset = 0;
+         }
+       else
+         {
+           x_unknown = 1;
+         }
+       if (GET_CODE (y) == PLUS)
+         {
+           if (GET_CODE (XEXP (y, 1)) == CONST_INT)
+             {
+               y_offset = XINT (XEXP (y, 1), 0);
+             }
+           else
+             {
+               y_unknown = 1;
+             }
+           if (GET_CODE (XEXP (y, 0)) == REG
+               && ((frame_pointer_needed && XEXP (y, 0) == frame_pointer_rtx)
+                   || XEXP (y, 0) == stack_pointer_rtx))
+             {
+               ; /* ok */
+             }
+           else
+             {
+               y_unknown = 1;
+             }
+         }
+       else
+       if (GET_CODE (y) == REG
+           && ((frame_pointer_needed && y == frame_pointer_rtx)
+               || y == stack_pointer_rtx))
+         {
+          y_offset = 0;
+         }
+       else
+         {
+           y_unknown = 1;
+         }
+       if (x_unknown == 0  && y_unknown == 0)
+         {
+           if (x_offset < y_offset)
+             return (!(x_offset + xsize <= y_offset));
+           else
+             return (!(y_offset + ysize <= x_offset));
+         } 
+     }
+   
    if (rtx_equal_for_memref_p (x, y))
      return (xsize == 0 || ysize == 0 ||
  	    (c >= 0 && xsize > c) || (c < 0 && ysize+c > 0));
***************
*** 922,928 ****
--- 1194,1208 ----
  	 SCHED_GROUP_P.  */
        while (NEXT_INSN (next) && SCHED_GROUP_P (NEXT_INSN (next))
  	     && GET_CODE (NEXT_INSN (next)) != CODE_LABEL)
+       {
+         /* intel1 - next might already be part of this SCHED_GROUP,
+         */
+         if(next==insn )
+         {
+ 	  return;
+         }
  	next = NEXT_INSN (next);
+       }
  
        /* Again, don't depend an insn on itself.  */
        if (insn == next)
***************
*** 956,962 ****
  /* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
     of INSN.  Abort if not found.  */
  
! static void
  remove_dependence (insn, elem)
       rtx insn;
       rtx elem;
--- 1236,1242 ----
  /* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
     of INSN.  Abort if not found.  */
  
! void
  remove_dependence (insn, elem)
       rtx insn;
       rtx elem;
***************
*** 1217,1225 ****
--- 1497,1518 ----
        if (function_units[unit].blockage_range_function)
  	{
  	  if (function_units[unit].blockage_function)
+ 	    {
+ 	    /* intel1 */
+ #ifdef ADJUST_BLOCKAGE
+             {
+               int blockage = (function_units[unit].blockage_function
+ 		       (insn, unit_last_insn[instance]));
+ 	      ADJUST_BLOCKAGE (unit_last_insn[instance], insn, blockage);
+ 	      tick +=  blockage 
+ 		       - function_units[unit].max_blockage;
+ 	    }
+ #else
  	    tick += (function_units[unit].blockage_function
  		     (insn, unit_last_insn[instance])
  		     - function_units[unit].max_blockage);
+ #endif
+ 	    }
  	  else
  	    tick += ((int) MAX_BLOCKAGE_COST (blockage_range (unit, insn))
  		     - function_units[unit].max_blockage);
***************
*** 1706,1711 ****
--- 1999,2031 ----
  		/* Function calls clobber all call_used regs.  */
  		add_dependence (insn, last_function_call, REG_DEP_ANTI);
  	    }
+ #ifdef SMALL_REGISTER_CLASSES
+ /* intel1 
+    lifetime of hard registers must not be changed so this
+    insn becomes a pivot in the block.
+ */
+           if(reload_completed==0 && regno!=STACK_POINTER_REGNUM
+              && regno!=FRAME_POINTER_REGNUM)
+             {
+               rtx tinsn;
+ 
+               tinsn = first_insn_to_pivot;
+               while(tinsn!=insn)
+                 {
+                   if(GET_CODE(tinsn)==INSN || GET_CODE(tinsn)==CALL_INSN)
+                   {
+                     add_dependence (insn,tinsn,0);
+                   }
+                   tinsn = NEXT_INSN(tinsn);
+                 }
+               if(last_hard_reg_insn)
+                 {
+                   add_dependence (insn,last_hard_reg_insn,0);
+                 }
+               first_insn_to_pivot = insn; 
+               last_hard_reg_insn = insn;
+             }
+ #endif
  	}
        else
  	{
***************
*** 1806,1811 ****
--- 2126,2151 ----
    if (x == 0)
      return;
  
+ /* intel1 */
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ #ifdef NO_STACK_REG_REORDER
+   if (NO_STACK_REG_REORDER)
+     {
+       if (prev_stack_reg_insn!=NULL && insn!=prev_stack_reg_insn
+          && IS_STACK_MODE (GET_MODE (x)))
+         {
+ 	    add_dependence (insn, prev_stack_reg_insn, REG_DEP_TMP);
+         }
+       if (IS_STACK_MODE (GET_MODE (x)))
+         {
+           prev_stack_reg_insn = insn;
+         }
+     }
+ #endif
+ #endif
+ #endif
+ 
    code = GET_CODE (x);
  
    switch (code)
***************
*** 1871,1876 ****
--- 2211,2243 ----
  		  /* Function calls clobber all call_used regs.  */
  		  add_dependence (insn, last_function_call, REG_DEP_ANTI);
  	      }
+ #ifdef SMALL_REGISTER_CLASSES
+ /* intel1 
+    lifetime of hard registers must not be changed so this
+    insn becomes a pivot in the block.
+ */
+             if(reload_completed==0 && regno!=STACK_POINTER_REGNUM
+              && regno!=FRAME_POINTER_REGNUM)
+               {
+                 rtx tinsn;
+   
+                 tinsn = first_insn_to_pivot;
+                 while(tinsn!=insn)
+                   {
+                     if(GET_CODE(tinsn)==INSN || GET_CODE(tinsn)==CALL_INSN)
+                     {
+                       add_dependence (insn,tinsn,0);
+                     }
+                     tinsn = NEXT_INSN(tinsn);
+                   }
+                 if(last_hard_reg_insn)
+                   {
+                     add_dependence (insn,last_hard_reg_insn,0);
+                   }
+                 first_insn_to_pivot = insn; 
+                 last_hard_reg_insn = insn;
+               }
+ #endif
  	  }
  	else
  	  {
***************
*** 2023,2028 ****
--- 2390,2403 ----
    int maxreg = max_reg_num ();
    int i;
  
+ #ifdef SMALL_REGISTER_CLASSES
+ /* intel1 */
+   if (reload_completed==0 && last_hard_reg_insn!=NULL)
+     {
+       add_dependence (insn,last_hard_reg_insn,0);
+     }
+ #endif
+ 
    if (code == SET || code == CLOBBER)
      sched_analyze_1 (x, insn);
    else if (code == PARALLEL)
***************
*** 2170,2175 ****
--- 2545,2571 ----
    register int luid = 0;
    rtx loop_notes = 0;
  
+ /* intel1 */
+   rtx pinsn;
+ #ifdef STACK_REGS
+   pinsn = NULL;
+   if (maintain_order && reload_completed==0)
+     { /* A block we don't want to change order but keep track of
+          register life information.  */
+       for (insn = head; insn != tail; insn = NEXT_INSN (insn))
+         {
+           if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+             {
+               if (pinsn)
+                 {
+                   add_dependence (insn, pinsn, REG_DEP_TMP);
+                 }
+               pinsn = insn;
+             }
+         }
+     }
+ #endif
+ 
    for (insn = head; ; insn = NEXT_INSN (insn))
      {
        INSN_LUID (insn) = luid++;
***************
*** 2514,2519 ****
--- 2910,2931 ----
        rtx note;
        int n_deaths = 0;
  
+       /* intel1 */
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ #ifdef STACK_REG_REORDER
+       /* For stack registers don't take lifetimes into account */
+       if (birthing_insn_p (PATTERN (prev)) && STACK_REG_REORDER && 0)
+ 	{
+ 	  if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
+ 	      && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (prev)))))
+ 	    {
+ 	      return;
+ 	    }
+ 	}
+ #endif
+ #endif
+ #endif
        /* ??? This code has no effect, because REG_DEAD notes are removed
  	 before we ever get here.  */
        for (note = REG_NOTES (prev); note; note = XEXP (note, 1))
***************
*** 2724,2730 ****
  
    if (dead_notes == 0)
      {
! #if 1
        abort ();
  #else
        link = rtx_alloc (EXPR_LIST);
--- 3136,3143 ----
  
    if (dead_notes == 0)
      {
! /* Sorry for this hack */
! #if 0
        abort ();
  #else
        link = rtx_alloc (EXPR_LIST);
***************
*** 3169,3178 ****
--- 3582,3625 ----
    register struct sometimes *regs_sometimes_live;
    int sometimes_max;
  
+   /* intel1 */
+ #ifdef HAVE_cc0
+   rtx prev_to_cc0_setter;
+ #endif
+ #ifdef AGI
+   int possible_agi = 0;
+ #endif
+ #ifdef NO_STACK_REG_REORDER
+   rtx tinsn, tlink, tprev_link;
+ #endif /* NO_STACK_REG_REORDER */
+ 
    if (file)
      fprintf (file, ";;\t -- basic block number %d from %d to %d --\n",
  	     b, INSN_UID (basic_block_head[b]), INSN_UID (basic_block_end[b]));
  
+ /* intel1 */
+ #ifdef NO_STACK_REG_REORDER
+   prev_stack_reg_insn = NULL;
+ #endif
+ #ifdef STACK_REGS
+   maintain_order = 0;
+   if (STACK_NON_STACK_INTERLEAVE || STACK_REG_REORDER)
+     {
+       rtx tinsn = head;
+       int found_stack_mode = 0;
+       while (tinsn && !found_stack_mode && tinsn != tail)
+         {
+           if (GET_CODE (tinsn) == INSN && GET_CODE (PATTERN (tinsn)) == SET
+               && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (tinsn)))))
+             {
+               found_stack_mode = 1;
+             }
+           tinsn = next_nonnote_insn (tinsn);
+         }
+       maintain_order = !found_stack_mode;
+     }
+ #endif
+ 
    i = max_reg_num ();
    reg_last_uses = (rtx *) alloca (i * sizeof (rtx));
    bzero ((char *) reg_last_uses, i * sizeof (rtx));
***************
*** 3264,3269 ****
--- 3711,3721 ----
  
    LOG_LINKS (sched_before_next_call) = 0;
  
+ #ifdef SMALL_REGISTER_CLASSES
+ /* intel1 */
+   first_insn_to_pivot = head;
+   last_hard_reg_insn = NULL;
+ #endif
    n_insns += sched_analyze (head, tail);
    if (n_insns == 0)
      {
***************
*** 3280,3285 ****
--- 3732,3823 ----
    /* TAIL is now the last of the insns to be rearranged.
       Put those insns into the READY vector.  */
    insn = tail;
+ /* intel1 */
+ #ifdef HAVE_cc0
+   /* intel1 further if we have done compare elimination then the
+      insn before the compare should not be moved */
+   if (head!=tail 
+      && GET_CODE (basic_block_end[b])==JUMP_INSN 
+      && GET_CODE (PATTERN (basic_block_end[b]))!=PARALLEL 
+      && GET_CODE (PATTERN (basic_block_end[b]))!=ADDR_VEC 
+      && GET_CODE (XEXP (SET_SRC (PATTERN (basic_block_end[b])),0))==NE 
+      && GET_CODE (PREV_INSN (basic_block_end[b]))==INSN 
+      && GET_CODE (PATTERN (PREV_INSN (basic_block_end[b])))==SET 
+      && SET_DEST (PATTERN (PREV_INSN (basic_block_end[b])))==cc0_rtx 
+      && GET_CODE (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))))==COMPARE 
+      && XEXP (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))),1)==const0_rtx)
+     {
+       prev_to_cc0_setter = 
+         prev_nonnote_insn( PREV_INSN (basic_block_end[b]));
+       if (! (prev_to_cc0_setter && RTX_IS_RISC_P (prev_to_cc0_setter))
+          && prev_insts_in_block (b,PREV_INSN (basic_block_end[b])) 
+          && (head != PREV_INSN (basic_block_end[b])) )
+         {
+           SCHED_GROUP_P (PREV_INSN (basic_block_end[b]))=1;
+           /* Also must remove the 
+              prev_nonnote_insn(PREV_INSN(basic_block_end[b]) from the
+              dependency chain of both basic_block_end[b] and
+              PREV_INSN(basic_block_end[b]), to ensure that it doesn't
+              go through the ready list also */
+           if(prev_to_cc0_setter 
+              && (GET_CODE (prev_to_cc0_setter)==INSN 
+                  || GET_CODE (prev_to_cc0_setter)==CALL_INSN )
+ 	     && ! RTX_IS_RISC_P (prev_to_cc0_setter))  /* intel2 */
+             {
+ 	      if (find_insn_list (prev_to_cc0_setter, 
+ 	                          LOG_LINKS (PREV_INSN (basic_block_end[b]))))
+ 	        remove_dependence (PREV_INSN (basic_block_end[b]), 
+ 	                           prev_to_cc0_setter);
+ 	      if (find_insn_list (prev_to_cc0_setter, 
+ 	                          LOG_LINKS ( basic_block_end[b])))
+ 	        remove_dependence (basic_block_end[b], 
+ 	                           prev_to_cc0_setter);
+ 	    }
+         }
+       else
+         SCHED_GROUP_P(PREV_INSN(basic_block_end[b]))=0;
+     } 
+   else
+   if (head!=tail 
+      && GET_CODE (basic_block_end[b])==JUMP_INSN 
+      && GET_CODE (PATTERN (basic_block_end[b]))!=PARALLEL 
+      && GET_CODE (PATTERN (basic_block_end[b]))!=ADDR_VEC 
+      && GET_CODE (PREV_INSN (basic_block_end[b]))==INSN 
+      && GET_CODE (PATTERN (PREV_INSN (basic_block_end[b])))==SET 
+      && SET_DEST (PATTERN (PREV_INSN (basic_block_end[b])))==cc0_rtx 
+      && GET_CODE (SET_SRC (PATTERN (PREV_INSN (basic_block_end[b]))))!=COMPARE)
+     {
+       prev_to_cc0_setter = 
+         prev_nonnote_insn( PREV_INSN (basic_block_end[b]));
+       if (! (prev_to_cc0_setter && RTX_IS_RISC_P (prev_to_cc0_setter))
+          && prev_insts_in_block (b,PREV_INSN (basic_block_end[b])) 
+          && (head != PREV_INSN (basic_block_end[b])) )
+         {
+           SCHED_GROUP_P (PREV_INSN (basic_block_end[b]))=1;
+           /* Also must remove the 
+              prev_nonnote_insn(PREV_INSN(basic_block_end[b]) from the
+              dependency chain of both basic_block_end[b] and
+              PREV_INSN(basic_block_end[b]), to ensure that it doesn't
+              go through the ready list also */
+           if(prev_to_cc0_setter 
+              && (GET_CODE (prev_to_cc0_setter) == INSN 
+                  || GET_CODE (prev_to_cc0_setter) == CALL_INSN )
+ 	     && ! RTX_IS_RISC_P (prev_to_cc0_setter))  /* intel2 */
+             {
+ 	      if (find_insn_list (prev_to_cc0_setter, 
+ 	                          LOG_LINKS (PREV_INSN (basic_block_end[b]))))
+ 	        remove_dependence (PREV_INSN (basic_block_end[b]), 
+ 	                           prev_to_cc0_setter);
+ 	      if (find_insn_list (prev_to_cc0_setter, 
+ 	                          LOG_LINKS ( basic_block_end[b])))
+ 	        remove_dependence (basic_block_end[b], 
+ 	                           prev_to_cc0_setter);
+ 	    }
+         }
+       else
+         SCHED_GROUP_P(PREV_INSN(basic_block_end[b]))=0;
+     } 
+ #endif
  
    /* For all branches, calls, uses, and cc0 setters, force them to remain
       in order at the end of the block by adding dependencies and giving
***************
*** 3697,3710 ****
  		for (; insn; insn = NEXT_INSN (insn))
  		  {
  		    if (file)
! 		      fprintf (file, ";; launching %d before %d with %d stalls at T-%d\n",
! 			       INSN_UID (insn), INSN_UID (last), stalls, clock);
  		    ready[new_ready++] = insn;
  		    q_size -= 1;
  		  }
  		insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
  		break;
  	      }
  
  	  q_ptr = NEXT_Q_AFTER (q_ptr, stalls); clock += stalls;
  	}
--- 4235,4253 ----
  		for (; insn; insn = NEXT_INSN (insn))
  		  {
  		    if (file)
! 		      fprintf (file, ";; launching %d before %d with %d stalls at T-%d i_q[%d]\n",
! 			       INSN_UID (insn), INSN_UID (last), stalls, clock, new_ready);
  		    ready[new_ready++] = insn;
  		    q_size -= 1;
  		  }
  		insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = 0;
  		break;
  	      }
+          /* intel1 */
+ #ifdef AGI
+           if (new_ready == 1)
+             possible_agi = 1;
+ #endif
  
  	  q_ptr = NEXT_Q_AFTER (q_ptr, stalls); clock += stalls;
  	}
***************
*** 3715,3721 ****
  
        if (file)
  	{
! 	  fprintf (file, ";; ready list at T-%d:", clock);
  	  for (i = 0; i < new_ready; i++)
  	    fprintf (file, " %d (%x)",
  		     INSN_UID (ready[i]), INSN_PRIORITY (ready[i]));
--- 4258,4265 ----
  
        if (file)
  	{
! 	  fprintf (file, ";; ready list at T-%d (new_r %d n_r %d):", 
! 	  clock, new_ready, n_ready);
  	  for (i = 0; i < new_ready; i++)
  	    fprintf (file, " %d (%x)",
  		     INSN_UID (ready[i]), INSN_PRIORITY (ready[i]));
***************
*** 3934,3939 ****
--- 4478,4498 ----
  	      INSN_PRIORITY (insn) = DONE_PRIORITY;
  	    }
  	}
+ #ifdef AGI
+       if (possible_agi && reload_completed && flag_swap_for_agi)
+         {
+           rtx next_to_last = NEXT_INSN (last);	
+           if (try_eliminate_agi (last, file))
+             { /* last has been swapped downwards */
+               if (PREV_INSN (last) == tail)
+                 { /* last has moved down to become tail */
+                   tail = last;
+                 }
+               last = next_to_last;
+               insn = last;
+             }
+         }
+ #endif
      }
    if (q_size != 0)
      abort ();
***************
*** 3946,3951 ****
--- 4505,4538 ----
       TAIL is the last of those insns.  */
    head = insn;
  
+ /* intel1 */
+ #ifdef NO_STACK_REG_REORDER
+   if (NO_STACK_REG_REORDER)
+     { /* remove all the REG_DEP_TMP dependencies that were added */
+       for (tinsn = head; tinsn != NEXT_INSN (tail); tinsn = NEXT_INSN (tinsn))
+         {
+ 	  tlink = LOG_LINKS (tinsn); 
+ 	  tprev_link = tlink;
+ 	  while (tlink) 
+ 	    {
+ 	      if (REG_NOTE_KIND (tlink) == REG_DEP_TMP)
+ 	        {
+ 	          if (tlink == LOG_LINKS (tinsn))
+ 	            {
+ 	              LOG_LINKS (tinsn) = XEXP (tlink, 1);
+ 	            }
+ 	          else
+ 	            {
+ 	              XEXP (tprev_link, 1) = XEXP (tlink, 1);
+ 	            }
+ 	        }
+ 	      tprev_link = tlink;
+ 	      tlink = XEXP (tlink, 1);
+ 	    }
+         }
+     }
+ #endif /* NO_STACK_REG_REORDER */
+ 
    /* NOTE_LIST is the end of a chain of notes previously found
       among the insns.  Insert them at the beginning of the insns.  */
    if (note_list != 0)
***************
*** 4670,4680 ****
--- 5257,5355 ----
    int b;
    rtx insn;
  
+   cur_dump_file = dump_file;
    /* Taking care of this degenerate case makes the rest of
       this code simpler.  */
    if (n_basic_blocks == 0)
      return;
  
+   /* intel1 */
+ #ifdef STACK_REGS
+   if (STACK_NON_STACK_INTERLEAVE || STACK_REG_REORDER)
+     {
+       rtx tinsn = get_insns();
+       int found_stack_mode = 0;
+       while (tinsn && !found_stack_mode)
+         {
+           if (GET_CODE (tinsn) == INSN && GET_CODE (PATTERN (tinsn)) == SET
+               && IS_STACK_MODE (GET_MODE (SET_DEST (PATTERN (tinsn)))))
+             {
+               found_stack_mode = 1;
+             }
+           tinsn = next_nonnote_insn (tinsn);
+         }
+       if (!found_stack_mode) /* Nothing to do */
+         {
+           unused_insn_list = 0;
+           unused_expr_list = 0;
+           return;
+         }
+     }
+ #endif
+     /* intel1 - Remove all LOG_LINK information as the reload pass
+        may have invalidated some LOG_LINKs eg:
+        before reload:
+        (insn 21 20 24 (set (reg:SI 25)
+                (ashiftrt:SI (reg/v:SI 22)
+                    (const_int 3))) 142 {ashrsi3} (nil)
+            (nil))
+ 
+        (insn 24 21 28 (set (reg/v:SI 22)
+                (and:SI (reg/v:SI 22)
+                    (const_int 7))) 102 {andsi3} (nil)
+            (nil))
+ 
+        (insn 28 24 29 (set (reg:QI 27)
+                (and:QI (mem:QI (plus:SI (reg:SI 25)
+                            (symbol_ref:SI ("buf"))))
+                    (mem/s:QI (plus:SI (reg/v:SI 22)
+                            (symbol_ref:SI ("rmask")))))) 104 {andqi3}
+            (insn_list 21 (insn_list 24 (nil)))
+            (nil))
+ 
+        after reload:
+        (insn:HI 21 281 24 (set (reg:SI %edx)
+                (ashiftrt:SI (reg:SI %edx)
+                    (const_int 3))) 142 {ashrsi3} (nil)
+            (nil))
+ 
+ 
+        (insn 24 21 284 (set (reg/v:SI %ebp)
+                (and:SI (reg/v:SI %ebp)
+                    (const_int 7))) 102 {andsi3} (nil)
+            (nil))
+ 
+        (insn 284 24 28 (set (reg:QI %cl)
+                (mem:QI (plus:SI (reg:SI %edx)
+                        (symbol_ref:SI ("buf"))))) -1 (nil)
+            (nil))
+ 
+        (insn:HI 28 284 285 (set (reg:QI %cl)
+                (and:QI (reg:QI %cl)
+                    (mem/s:QI (plus:SI (reg/v:SI %ebp)
+                            (symbol_ref:SI ("rmask")))))) 104 {andqi3}
+            (insn_list 21 (insn_list 24 (nil)))
+             (nil))
+ 
+      Note that the LOG_LINKs of insn 28 is no longer valid - it does
+      not depend directly on insn 21 any longer. Leaving the LOG_LINKs
+      as they are may produce suboptimal, although valid, schedules.
+      */
+   if (reload_completed)
+     {
+       rtx tinsn = get_insns();
+       while (tinsn)
+         {
+           if (GET_CODE (tinsn) == INSN || GET_CODE (tinsn) == CALL_INSN
+               || GET_CODE (tinsn) == JUMP_INSN)
+             {
+               LOG_LINKS (tinsn) = NULL;
+             }
+           tinsn = next_nonnote_insn (tinsn);
+         }
+     }
+ 
+ 
    /* Create an insn here so that we can hang dependencies off of it later.  */
    sched_before_next_call
      = gen_rtx (INSN, VOIDmode, 0, NULL_RTX, NULL_RTX,
***************
*** 4815,4820 ****
--- 5490,5497 ----
  		  PUT_CODE (insn, NOTE);
  		  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
  		  NOTE_SOURCE_FILE (insn) = 0;
+ 		  /* intel1 */
+ 		  SCHED_GROUP_P(insn) = 0;
  		}
  
  	      continue;
***************
*** 4837,4842 ****
--- 5514,5521 ----
  		  PUT_CODE (insn, NOTE);
  		  NOTE_SOURCE_FILE (insn) = 0;
  		  NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 		  /* intel1 */
+ 		  SCHED_GROUP_P(insn) = 0;
  		  if (insn == basic_block_head[b])
  		    basic_block_head[b] = first;
  		  if (insn == basic_block_end[b])
***************
*** 4882,4887 ****
--- 5561,5568 ----
  		notes++;
  		NOTE_SOURCE_FILE (insn) = 0;
  		NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+ 		/* intel1 */
+ 		SCHED_GROUP_P(insn) = 0;
  	      }
  	    /* If the line number is unchanged, LINE is redundant.  */
  	    else if (line
***************
*** 4965,4968 ****
--- 5646,5931 ----
  	  }
      }
  }
+ /* intel1
+    return 1 if insn_b is part of the SCHED_GROUP of insn_a 
+ */
+ static int
+ is_part_of_group (insn_a, insn_b)
+      rtx insn_a;
+      rtx insn_b;
+ {
+   rtx pn;
+ 
+   pn = PREV_INSN(insn_a);
+   while(pn)
+     {
+       if(GET_CODE(pn)==INSN || GET_CODE(pn)==CALL_INSN ||
+          GET_CODE(pn)==JUMP_INSN)
+         {
+           if(pn==insn_b)
+             {
+               return(1);
+             }
+           if(!SCHED_GROUP_P(pn))
+             {
+               return(0);
+             }
+         }
+       pn = PREV_INSN(pn);
+     }
+   return(0);
+ }
+ 
+ /* intel1 return 1 if there are insts in block b before insn */
+ static int prev_insts_in_block(b, insn)
+ int b;
+ rtx insn;
+ {
+   insn = PREV_INSN(insn);
+   while(insn && insn!=basic_block_head[b])
+     {
+       if(GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+         {
+           return(1);
+         }
+       insn = PREV_INSN(insn);
+     }
+   if(insn && 
+      insn==basic_block_head[b] && GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+     {
+       return(1);
+     }
+   return(0);
+ }
+ 
+ #ifdef AGI
+ /* intel1
+   If insn updates a register by a constant and NEXT_INSN (insn) uses
+   that register as a base or index and this is the only dependence
+   between the two insns - then try to swap these two insns by replacing
+   register with (register + constant) in NEXT_INSN (insn).  
+ */
+ int try_eliminate_agi (insn, file)
+   rtx insn;
+   FILE * file;
+ {
+   rtx next;
+   int success;
+   
+   next = NEXT_INSN (insn);
+   if (!try_swap (insn))
+     {
+       return (0);
+     }
+   /* Now swap insn with next.  */
+   PREV_INSN (NEXT_INSN (next)) = insn;
+   NEXT_INSN (insn) = NEXT_INSN (next);
+   NEXT_INSN (next) = insn;
+   PREV_INSN (insn) = next;
+   success = 1;
+   if (file)
+     {
+       fprintf (file, ";; swapped %d with %d to eliminate agi, %d is last scheduled\n",
+       INSN_UID (insn), INSN_UID (next), INSN_UID (next));
+     }
+   while (success)
+     {  /* Keep trying to swap insn downwards */
+       success = try_swap (insn);
+       if (success)
+         {
+           next = NEXT_INSN (insn);
+           if (file)
+             {
+               fprintf (file, ";;   (swapped %d with %d to eliminate agi)\n",
+               INSN_UID (insn), INSN_UID (next));
+             }
+           NEXT_INSN (PREV_INSN (insn)) = next;
+           PREV_INSN (next) = PREV_INSN (insn);
+           PREV_INSN (NEXT_INSN (next)) = insn;
+           NEXT_INSN (insn) = NEXT_INSN (next);
+           NEXT_INSN (next) = insn;
+           PREV_INSN (insn) = next;
+         }
+     }
+   return (1);
+ }
+ 
+ int try_swap (insn)
+   rtx insn;
+ {
+   rtx next, tmp, src, dest, next_src, next_dest, reg_to_update,
+       copy_dest, copy_src;
+   int offst_update, updates_by_const, regno_updated, length, i,
+       insn_code_number, save_code;
+   char * fmt, * storage;
+   next = NEXT_INSN (insn);
+   if (GET_CODE (insn) != INSN || next == NULL || GET_CODE (next) != INSN
+       || GET_CODE (PATTERN (insn)) != SET || GET_CODE (PATTERN (next)) != SET)
+     {
+       return (0);
+     }
+   src = SET_SRC (PATTERN (insn));
+   dest = SET_DEST (PATTERN (insn));
+   next_src = SET_SRC (PATTERN (next));
+   next_dest = SET_DEST (PATTERN (next));
+   if (next_dest == cc0_rtx)
+     {
+       return (0);
+     }
+   if (rtx_equal_p (dest, next_dest))
+     {
+       return (0);
+     }
+   if (GET_CODE (next_dest) == REG)
+     {
+       if (reg_overlap_mentioned_p (next_dest, PATTERN (insn)))
+         {
+           return (0);
+         }
+     }
+   /* See if insn updates some register by a constant ammount */
+   updates_by_const = 0;
+   if (GET_CODE (dest) == REG)
+     {
+       if ((GET_CODE (src) == PLUS || GET_CODE (src) == MINUS)
+           && rtx_equal_p (XEXP (src, 0), dest) 
+           && GET_CODE (XEXP (src, 1)) == CONST_INT)
+         {
+           updates_by_const = 1;
+           offst_update 
+             = XINT (XEXP (src, 1), 0) * (GET_CODE (src) == PLUS ? 1 : -1);
+           regno_updated = REGNO (dest);
+           reg_to_update = dest;
+         }
+     }
+   if (GET_CODE (dest) == MEM && push_operand (dest, GET_MODE (dest))
+       && (GET_CODE (src) == REG
+           || (GET_CODE (src) == MEM && !side_effects_p (XEXP (src, 0)))))
+     {
+       updates_by_const = 1;
+       offst_update = GET_MODE_SIZE (GET_MODE (dest));
+       if (GET_CODE (XEXP (dest, 0)) == PRE_DEC ||
+           GET_CODE (XEXP (dest, 0)) == POST_DEC)
+         {
+           offst_update *= -1;
+         }
+       regno_updated = STACK_POINTER_REGNUM;
+       reg_to_update = stack_pointer_rtx;
+     }
+   if (!updates_by_const)
+     {
+       return (0);
+     }
+   if (!reg_overlap_mentioned_p (reg_to_update, PATTERN (next)))
+     {
+       return (0);
+     }
+   if (GET_CODE (dest) == MEM)
+     {
+       if (GET_CODE (next_src) == MEM
+            && true_dependence (dest, next_src))
+         {
+           return (0);
+         }
+       else if (GET_CODE (next_src) != REG)
+         {
+           fmt = GET_RTX_FORMAT (GET_CODE (next_src));
+           length = GET_RTX_LENGTH (GET_CODE (next_src));
+           for (i=0; i<length; i++)
+             {
+               if (fmt[i] == 'e' && GET_CODE (XEXP (next_src, i)) == MEM)
+                 {
+                   if (true_dependence (dest, XEXP (next_src, i)))
+                     {
+                       return (0);
+                     }
+                 }
+             }
+         }
+       if (GET_CODE (next_dest) == MEM
+            && true_dependence (dest, next_dest))
+         {
+           return (0);
+         }
+     }
+   if (GET_CODE (src) == MEM)
+     {
+       if (GET_CODE (next_dest) == MEM
+            && true_dependence (src, next_dest))
+         {
+           return (0);
+         }
+     }
+   /* First check that regno_updated is not used in next with any
+      other mode */
+   init_undo_buf ();
+   subst_in_insn (next, PATTERN (next), reg_to_update, const0_rtx, 0, 0);
+   if (reg_overlap_mentioned_p (reg_to_update, PATTERN (next)))
+     {
+       loop_undo_all ();
+       return (0);
+     }
+   loop_undo_all ();
+   /* Now substitute reg_to_update with  reg_to_update + offst_update.  */
+   storage = (char *) oballoc (0);
+   /* Since may be sharing of rtl */
+   copy_dest = copy_rtx (next_dest);
+   copy_src = copy_rtx (next_src);
+   SET_SRC (PATTERN (next)) = copy_src;
+   SET_DEST (PATTERN (next)) = copy_dest;
+   init_undo_buf ();
+   subst_in_insn (next, PATTERN (next), reg_to_update,
+                  gen_rtx (PLUS , GET_MODE (reg_to_update), reg_to_update,
+                           gen_rtx (CONST_INT, 0, offst_update)), 0, 0);
+ #ifdef REWRITE_ADDRESS
+   if (GET_CODE (copy_dest) == MEM)
+     {
+       REWRITE_ADDRESS (copy_dest);
+     }
+   if (GET_CODE (copy_src) == MEM)
+     {
+       REWRITE_ADDRESS (copy_src);
+     }
+   else
+     {
+       fmt = GET_RTX_FORMAT (GET_CODE (copy_src));
+       length = GET_RTX_LENGTH (GET_CODE (copy_src));
+       for (i=0; i<length; i++)
+         {
+           if (fmt[i] == 'e' && GET_CODE (XEXP (copy_src, i)) == MEM)
+             {
+               REWRITE_ADDRESS (XEXP (copy_src, i));
+             }
+         }
+     }
+ #endif
+   if ((insn_code_number = recog (PATTERN (next), next, 0)) < 0)
+     {
+       loop_undo_all ();
+       SET_DEST (PATTERN (next)) = next_dest;
+       SET_SRC (PATTERN (next)) = next_src;
+       obfree (storage);
+       return (0);
+     }
+   else
+     {
+ #ifdef REGISTER_CONSTRAINTS
+       save_code = INSN_CODE (next);
+       INSN_CODE (next) = insn_code_number;
+       insn_extract (next);
+       if (!constrain_operands (insn_code_number, 1))
+ 	{
+ 	  loop_undo_all ();
+           SET_DEST (PATTERN (next)) = next_dest;
+           SET_SRC (PATTERN (next)) = next_src;
+ 	  INSN_CODE (next) = save_code;
+           obfree (storage);
+ 	  return (0);
+ 	}
+ #endif
+     }
+   return (1);
+ }
+ #endif
+ 
  #endif /* INSN_SCHEDULING */
diff -rNci gcc-2.7.2/stmt.c gcc-2.7.2p/stmt.c
*** gcc-2.7.2/stmt.c	Tue Sep 12 23:01:54 1995
--- gcc-2.7.2p/stmt.c	Thu Jun 15 12:08:17 1995
***************
*** 467,472 ****
--- 467,482 ----
  static void emit_jump_if_reachable	PROTO((rtx));
  static void emit_case_nodes		PROTO((rtx, case_node_ptr, rtx, tree));
  
+ int bc_expand_exit_loop_if_false ();
+ void bc_expand_start_cond ();
+ void bc_expand_end_cond ();
+ void bc_expand_start_else ();
+ void bc_expand_end_bindings ();
+ void bc_expand_start_case ();
+ void bc_check_for_full_enumeration_handling ();
+ void bc_expand_end_case ();
+ void bc_expand_decl ();
+ 
  extern rtx bc_allocate_local ();
  extern rtx bc_allocate_variable_array ();
  
***************
*** 553,560 ****
        last_insn = get_last_insn ();
        if (!optimize
  	  && (GET_CODE (last_insn) == CODE_LABEL
! 	      || (GET_CODE (last_insn) == NOTE
! 		  && prev_real_insn (last_insn) == 0)))
  	emit_insn (gen_nop ());
      }
  }
--- 563,569 ----
        last_insn = get_last_insn ();
        if (!optimize
  	  && (GET_CODE (last_insn) == CODE_LABEL
! 	      || prev_real_insn (last_insn) == 0))
  	emit_insn (gen_nop ());
      }
  }
***************
*** 1246,1252 ****
  	      f->before_jump
  		= emit_insns_after (cleanup_insns, f->before_jump);
  
! 	      f->cleanup_list_list = TREE_CHAIN (lists);
  	    }
  
  	if (stack_level)
--- 1255,1261 ----
  	      f->before_jump
  		= emit_insns_after (cleanup_insns, f->before_jump);
  
! 	      TREE_VALUE (lists) = 0;
  	    }
  
  	if (stack_level)
***************
*** 1508,1514 ****
    for (tail = inputs; tail; tail = TREE_CHAIN (tail))
      {
        int j;
-       int allows_reg = 0;
  
        /* If there's an erroneous arg, emit no insn,
  	 because the ASM_INPUT would get VOIDmode
--- 1517,1522 ----
***************
*** 1524,1588 ****
  
        /* Make sure constraint has neither `=' nor `+'.  */
  
!       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)) - 1; j++)
! 	switch (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j])
  	  {
- 	  case '+':   case '=':
  	    error ("input operand constraint contains `%c'",
  		   TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
  	    return;
- 
- 	  case '?':  case '!':  case '*':  case '%':  case '&':
- 	  case 'V':  case 'm':  case 'o':  case '<':  case '>':
- 	  case 'E':  case 'F':  case 'G':  case 'H':  case 'X':
- 	  case 's':  case 'i':  case 'n':
- 	  case 'I':  case 'J':  case 'K':  case 'L':  case 'M':
- 	  case 'N':  case 'O':  case 'P':  case ',':
- #ifdef EXTRA_CONSTRAINT
- 	  case 'Q':  case 'R':  case 'S':  case 'T':  case 'U':
- #endif
- 	    break;
- 
- 	  case '0':  case '1':  case '2':  case '3':  case '4':
- 	  case 'p':  case 'g':  case 'r':
- 	  default:
- 	    allows_reg = 1;
- 	    break;
  	  }
  
-       if (! allows_reg)
- 	mark_addressable (TREE_VALUE (tail));
- 
        XVECEXP (body, 3, i)      /* argvec */
  	= expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
        if (CONSTANT_P (XVECEXP (body, 3, i))
  	  && ! general_operand (XVECEXP (body, 3, i),
  				TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
! 	{
! 	  if (allows_reg)
! 	    XVECEXP (body, 3, i)
! 	      = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
! 			   XVECEXP (body, 3, i));
! 	  else
! 	    XVECEXP (body, 3, i)
! 	      = force_const_mem (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
! 				 XVECEXP (body, 3, i));
! 	}
! 
!       if (! allows_reg
! 	  && (GET_CODE (XVECEXP (body, 3, i)) == REG
! 	      || GET_CODE (XVECEXP (body, 3, i)) == SUBREG
! 	      || GET_CODE (XVECEXP (body, 3, i)) == CONCAT))
! 	{
! 	  tree type = TREE_TYPE (TREE_VALUE (tail));
! 	  rtx memloc = assign_stack_temp (TYPE_MODE (type),
! 					  int_size_in_bytes (type), 1);
! 
! 	  MEM_IN_STRUCT_P (memloc) = AGGREGATE_TYPE_P (type);
! 	  emit_move_insn (memloc, XVECEXP (body, 3, i));
! 	  XVECEXP (body, 3, i) = memloc;
! 	}
! 	  
        XVECEXP (body, 4, i)      /* constraints */
  	= gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  		   TREE_STRING_POINTER (TREE_PURPOSE (tail)));
--- 1532,1554 ----
  
        /* Make sure constraint has neither `=' nor `+'.  */
  
!       for (j = 0; j < TREE_STRING_LENGTH (TREE_PURPOSE (tail)); j++)
! 	if (TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '='
! 	    || TREE_STRING_POINTER (TREE_PURPOSE (tail))[j] == '+')
  	  {
  	    error ("input operand constraint contains `%c'",
  		   TREE_STRING_POINTER (TREE_PURPOSE (tail))[j]);
  	    return;
  	  }
  
        XVECEXP (body, 3, i)      /* argvec */
  	= expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
        if (CONSTANT_P (XVECEXP (body, 3, i))
  	  && ! general_operand (XVECEXP (body, 3, i),
  				TYPE_MODE (TREE_TYPE (TREE_VALUE (tail)))))
! 	XVECEXP (body, 3, i)
! 	  = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
! 		       XVECEXP (body, 3, i));
        XVECEXP (body, 4, i)      /* constraints */
  	= gen_rtx (ASM_INPUT, TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))),
  		   TREE_STRING_POINTER (TREE_PURPOSE (tail)));
***************
*** 1885,1891 ****
    momentary = suspend_momentary ();
    t = make_node (RTL_EXPR);
    resume_momentary (momentary);
-   do_pending_stack_adjust ();
    start_sequence_for_rtl_expr (t);
    NO_DEFER_POP;
    expr_stmts_for_value++;
--- 1851,1856 ----
***************
*** 2757,2816 ****
        && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
        && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
      {
!       int i, bitpos, xbitpos;
        int big_endian_correction = 0;
        int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
        int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-       int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
        rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
!       rtx result_reg, src, dst;
        rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
        enum machine_mode tmpmode, result_reg_mode;
  
!       /* Structures whose size is not a multiple of a word are aligned
! 	 to the least significant byte (to the right).  On a BYTES_BIG_ENDIAN
! 	 machine, this means we must skip the empty high order bytes when
! 	 calculating the bit offset.  */
!       if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
! 	big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
! 						  * BITS_PER_UNIT));
! 
!       /* Copy the structure BITSIZE bits at a time.  */ 
!       for (bitpos = 0, xbitpos = big_endian_correction;
! 	   bitpos < bytes * BITS_PER_UNIT;
! 	   bitpos += bitsize, xbitpos += bitsize)
! 	{
! 	  /* We need a new destination pseudo each time xbitpos is
! 	     on a word boundary and when xbitpos == big_endian_correction
! 	     (the first time through).  */
! 	  if (xbitpos % BITS_PER_WORD == 0
! 	      || xbitpos == big_endian_correction)
  	    {
! 	      /* Generate an appropriate register.  */
! 	      dst = gen_reg_rtx (word_mode);
! 	      result_pseudos[xbitpos / BITS_PER_WORD] = dst;
  
! 	      /* Clobber the destination before we move anything into it.  */
! 	      emit_insn (gen_rtx (CLOBBER, VOIDmode, dst));
  	    }
- 
- 	  /* We need a new source operand each time bitpos is on a word
- 	     boundary.  */
- 	  if (bitpos % BITS_PER_WORD == 0)
- 	    src = operand_subword_force (result_val,
- 					 bitpos / BITS_PER_WORD,
- 					 BLKmode);
- 
- 	  /* Use bitpos for the source extraction (left justified) and
- 	     xbitpos for the destination store (right justified).  */
- 	  store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
- 			   extract_bit_field (src, bitsize,
- 					      bitpos % BITS_PER_WORD, 1,
- 					      NULL_RTX, word_mode,
- 					      word_mode,
- 					      bitsize / BITS_PER_UNIT,
- 					      BITS_PER_WORD),
- 			   bitsize / BITS_PER_UNIT, BITS_PER_WORD);
  	}
  
        /* Find the smallest integer mode large enough to hold the
--- 2722,2772 ----
        && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
        && GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) == REG)
      {
!       int i;
        int big_endian_correction = 0;
        int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
        int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
        rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
!       rtx result_reg;
        rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
        enum machine_mode tmpmode, result_reg_mode;
  
!       /* Structures smaller than a word are aligned to the least significant
! 	 byte (to the right).  On a BYTES_BIG_ENDIAN machine, this means we
! 	 must skip the empty high order bytes when calculating the bit
! 	 offset.  */
!       if (BYTES_BIG_ENDIAN && bytes < UNITS_PER_WORD)
! 	big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
! 
!       for (i = 0; i < n_regs; i++)
! 	{
! 	  rtx reg = gen_reg_rtx (word_mode);
! 	  rtx word = operand_subword_force (result_val, i, BLKmode);
! 	  int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),BITS_PER_WORD);
! 	  int bitpos;
! 
! 	  result_pseudos[i] = reg;
! 
! 	  /* Clobber REG and move each partword into it.  Ensure we don't
! 	     go past the end of the structure.  Note that the loop below
! 	     works because we've already verified that padding and
! 	     endianness are compatible.  */
! 	  emit_insn (gen_rtx (CLOBBER, VOIDmode, reg));
! 
! 	  for (bitpos = 0;
! 	       bitpos < BITS_PER_WORD && bytes > 0;
! 	       bitpos += bitsize, bytes -= bitsize / BITS_PER_UNIT)
  	    {
! 	      int xbitpos = bitpos + big_endian_correction;
  
! 	      store_bit_field (reg, bitsize, xbitpos, word_mode,
! 			       extract_bit_field (word, bitsize, bitpos, 1,
! 						  NULL_RTX, word_mode,
! 						  word_mode,
! 						  bitsize / BITS_PER_UNIT,
! 						  BITS_PER_WORD),
! 			       bitsize / BITS_PER_UNIT, BITS_PER_WORD);
  	    }
  	}
  
        /* Find the smallest integer mode large enough to hold the
***************
*** 3310,3316 ****
  }
  
  /* Generate RTL for the automatic variable declaration DECL.
!    (Other kinds of declarations are simply ignored if seen here.)  */
  
  void
  expand_decl (decl)
--- 3266,3287 ----
  }
  
  /* Generate RTL for the automatic variable declaration DECL.
!    (Other kinds of declarations are simply ignored if seen here.)
!    CLEANUP is an expression to be executed at exit from this binding contour;
!    for example, in C++, it might call the destructor for this variable.
! 
!    If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
!    either before or after calling `expand_decl' but before compiling
!    any subsequent expressions.  This is because CLEANUP may be expanded
!    more than once, on different branches of execution.
!    For the same reason, CLEANUP may not contain a CALL_EXPR
!    except as its topmost node--else `preexpand_calls' would get confused.
! 
!    If CLEANUP is nonzero and DECL is zero, we record a cleanup
!    that is not associated with any particular variable.
! 
!    There is no special support here for C++ constructors.
!    They should be handled by the proper code in DECL_INITIAL.  */
  
  void
  expand_decl (decl)
***************
*** 3683,3689 ****
     for example, in C++, it might call the destructor for this variable.
  
     If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
!    either before or after calling `expand_decl_cleanup' but before compiling
     any subsequent expressions.  This is because CLEANUP may be expanded
     more than once, on different branches of execution.
     For the same reason, CLEANUP may not contain a CALL_EXPR
--- 3654,3660 ----
     for example, in C++, it might call the destructor for this variable.
  
     If CLEANUP contains any SAVE_EXPRs, then you must preevaluate them
!    either before or after calling `expand_decl' but before compiling
     any subsequent expressions.  This is because CLEANUP may be expanded
     more than once, on different branches of execution.
     For the same reason, CLEANUP may not contain a CALL_EXPR
***************
*** 3726,3733 ****
    struct nesting *thisblock = block_stack;
    rtx x;
  
!   expand_decl (decl);
!   expand_decl_cleanup (decl, cleanup);
    x = DECL_RTL (decl);
  
    while (decl_elts)
--- 3697,3703 ----
    struct nesting *thisblock = block_stack;
    rtx x;
  
!   expand_decl (decl, cleanup);
    x = DECL_RTL (decl);
  
    while (decl_elts)
diff -rNci gcc-2.7.2/stor-layout.c gcc-2.7.2p/stor-layout.c
*** gcc-2.7.2/stor-layout.c	Tue Oct  3 23:15:07 1995
--- gcc-2.7.2p/stor-layout.c	Thu Jun 15 12:08:47 1995
***************
*** 81,96 ****
    return chain;
  }
  
- void
- put_pending_sizes (chain)
-      tree chain;
- {
-   if (pending_sizes)
-     abort ();
- 
-   pending_sizes = chain;
- }
- 
  /* Given a size SIZE that may not be a constant, return a SAVE_EXPR
     to serve as the actual size-expression for a type or decl.  */
  
--- 81,86 ----
***************
*** 747,774 ****
  	if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
  	    && TYPE_SIZE (element))
  	  {
! 	    tree ub = TYPE_MAX_VALUE (index);
! 	    tree lb = TYPE_MIN_VALUE (index);
! 	    tree length;
! 
! 	    /* If UB is max (lb - 1, x), remove the MAX_EXPR since the
! 	       test for negative below covers it.  */
! 	    if (TREE_CODE (ub) == MAX_EXPR
! 		&& TREE_CODE (TREE_OPERAND (ub, 0)) == MINUS_EXPR
! 		&& integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 0), 1))
! 		&& operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 0), 0),
! 				    lb, 0))
! 	      ub = TREE_OPERAND (ub, 1);
! 	    else if (TREE_CODE (ub) == MAX_EXPR
! 		     && TREE_CODE (TREE_OPERAND (ub, 1)) == MINUS_EXPR
! 		     && integer_onep (TREE_OPERAND (TREE_OPERAND (ub, 1), 1))
! 		     && operand_equal_p (TREE_OPERAND (TREE_OPERAND (ub, 1),
! 						       0),
! 					 lb, 0))
! 	      ub = TREE_OPERAND (ub, 0);
! 
! 	    length = size_binop (PLUS_EXPR, size_one_node,
! 				 size_binop (MINUS_EXPR, ub, lb));
  
  	    /* If neither bound is a constant and sizetype is signed, make
  	       sure the size is never negative.  We should really do this
--- 737,746 ----
  	if (index && TYPE_MAX_VALUE (index) && TYPE_MIN_VALUE (index)
  	    && TYPE_SIZE (element))
  	  {
! 	    tree length
! 	      = size_binop (PLUS_EXPR, size_one_node,
! 			    size_binop (MINUS_EXPR, TYPE_MAX_VALUE (index),
! 					TYPE_MIN_VALUE (index)));
  
  	    /* If neither bound is a constant and sizetype is signed, make
  	       sure the size is never negative.  We should really do this
diff -rNci gcc-2.7.2/stupid.c gcc-2.7.2p/stupid.c
*** gcc-2.7.2/stupid.c	Sun Oct 29 12:45:22 1995
--- gcc-2.7.2p/stupid.c	Thu Jun 15 12:09:19 1995
***************
*** 423,441 ****
  
    if (code == SET || code == CLOBBER)
      {
!       if (SET_DEST (x) != 0
! 	  && (GET_CODE (SET_DEST (x)) == REG
! 	      || (GET_CODE (SET_DEST (x)) == SUBREG
! 		  && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
! 		  && (REGNO (SUBREG_REG (SET_DEST (x)))
! 		      >= FIRST_PSEUDO_REGISTER))))
  	{
  	  /* Register is being assigned.  */
! 	  /* If setting a SUBREG, we treat the entire reg as being set.  */
! 	  if (GET_CODE (SET_DEST (x)) == SUBREG)
! 	    regno = REGNO (SUBREG_REG (SET_DEST (x)));
! 	  else
! 	    regno = REGNO (SET_DEST (x));
  
  	  /* For hard regs, update the where-live info.  */
  	  if (regno < FIRST_PSEUDO_REGISTER)
--- 423,432 ----
  
    if (code == SET || code == CLOBBER)
      {
!       if (SET_DEST (x) != 0 && GET_CODE (SET_DEST (x)) == REG)
  	{
  	  /* Register is being assigned.  */
! 	  regno = REGNO (SET_DEST (x));
  
  	  /* For hard regs, update the where-live info.  */
  	  if (regno < FIRST_PSEUDO_REGISTER)
diff -rNci gcc-2.7.2/toplev.c gcc-2.7.2p/toplev.c
*** gcc-2.7.2/toplev.c	Fri Oct 20 21:56:35 1995
--- gcc-2.7.2p/toplev.c	Tue Jan 23 09:25:32 1996
***************
*** 205,211 ****
--- 201,209 ----
  int combine_dump = 0;
  int sched_dump = 0;
  int local_reg_dump = 0;
+ int memory_simplify_dump = 0; /* intel2 */
  int global_reg_dump = 0;
+ int loop2_dump = 0; /* intel1 */
  int sched2_dump = 0;
  int jump2_opt_dump = 0;
  int dbr_sched_dump = 0;
***************
*** 374,379 ****
--- 372,413 ----
  /* Nonzero enables strength-reduction in loop.c.  */
  
  int flag_strength_reduce = 0;
+ /* intel1 my optimization controllers */
+ int flag_opt_reg_use = 0;
+ int flag_all_mem_givs = 0;
+ int flag_reduce_index_givs = 0;
+ int flag_peep_spills = 0;
+ int flag_loop_after_global = 0;
+ int flag_jump_back = 0;
+ int flag_copy_prop = 0;
+ int flag_lift_stores = 0;
+ int flag_runtime_lift_stores = 0;
+ int flag_compare_elim = 0;
+ int flag_sign_extension_elim = 0;
+ int flag_sftwr_pipe = 0;
+ int flag_opt_jumps_out = 0;
+ int flag_replace_mem = 0;
+ int flag_replace_stack_mem = 0;
+ int flag_reg_reg_copy_opt = 0;
+ int flag_do_offload = 0;
+ int flag_opt_reg_stack = 0;
+ int flag_correct_cse_mistakes = 0;
+ int flag_push_load_into_loop = 0;
+ int flag_risc = 0;
+ int flag_risc_const = 0;
+ int flag_risc_mem_dest = 0;	/* intel2 */
+ int flag_replace_reload_regs = 0;
+ int flag_recombine = 0;
+ int flag_swap_for_agi = 0;
+ int flag_no_omit_frame_pointer = 0;
+ int flag_no_risc = 0;
+ int flag_no_risc_const = 0;
+ int flag_no_risc_mem_dest = 0;	/* intel2 */
+ int flag_no_recombine = 0;
+ int flag_schedule_stack_reg_insns = 0;
+ int flag_interleave_stack_non_stack = 0;
+ int flag_no_schedule_stack_reg_insns = 0;
+ int flag_no_interleave_stack_non_stack = 0;
  
  /* Nonzero enables loop unrolling in unroll.c.  Only loops for which the
     number of iterations can be calculated at compile-time (UNROLL_COMPLETELY,
***************
*** 567,573 ****
    {"verbose-asm", &flag_verbose_asm, 1},
    {"gnu-linker", &flag_gnu_linker, 1},
    {"pack-struct", &flag_pack_struct, 1},
!   {"bytecode", &output_bytecode, 1}
  };
  
  /* Table of language-specific options.  */
--- 601,642 ----
    {"verbose-asm", &flag_verbose_asm, 1},
    {"gnu-linker", &flag_gnu_linker, 1},
    {"pack-struct", &flag_pack_struct, 1},
!   {"bytecode", &output_bytecode, 1},
!   /* intel1 */
!   {"compare-elim", &flag_compare_elim, 1},
!   {"sign-extension-elim", &flag_sign_extension_elim, 1},
!   {"jump-back", &flag_jump_back, 1},
!   {"loop-after-global", &flag_loop_after_global, 1},
!   {"opt-reg-use", &flag_opt_reg_use, 1},
!   {"all-mem-givs", &flag_all_mem_givs, 1},
!   {"reduce-index-givs", &flag_reduce_index_givs, 1},
!   {"peep-spills", &flag_peep_spills, 1},
!   {"copy-prop", &flag_copy_prop, 1},
!   {"lift-stores", &flag_lift_stores, 1},
!   {"runtime-lift-stores", &flag_runtime_lift_stores, 1},
!   {"do-offload", &flag_do_offload, 1},
!   {"opt-reg-stack", &flag_opt_reg_stack, 1},
!   {"correct-cse-mistakes", &flag_correct_cse_mistakes, 1},
!   {"spl", &flag_sftwr_pipe, 1},
!   {"opt-jumps-out", &flag_opt_jumps_out, 1},
!   {"replace-mem", &flag_replace_mem, 1},
!   {"replace-stack-mem", &flag_replace_stack_mem, 1},
!   {"no-interleave-stack-non-stack", &flag_no_interleave_stack_non_stack, 1},
!   {"interleave-stack-non-stack", &flag_interleave_stack_non_stack, 1},
!   {"no-schedule-stack-reg-insns", &flag_no_schedule_stack_reg_insns, 1},
!   {"schedule-stack-reg-insns", &flag_schedule_stack_reg_insns, 1},
!   {"reg-reg-copy-opt", &flag_reg_reg_copy_opt, 1},
!   {"push-load-into-loop", &flag_push_load_into_loop, 1},
!   {"swap-for-agi", &flag_swap_for_agi, 1},
!   {"no-recombine", &flag_no_recombine, 1},
!   {"recombine", &flag_recombine, 1},
!   {"no-risc", &flag_no_risc, 1},
!   {"risc", &flag_risc, 1},
!   {"no-risc-const", &flag_no_risc_const, 1},
!   {"risc-const", &flag_risc_const, 1},
!   {"replace-reload-regs", &flag_replace_reload_regs, 1},
!   {"no-risc-mem-dest", &flag_no_risc_mem_dest, 1},	/* intel2 */
!   {"risc-mem-dest", &flag_risc_mem_dest, 1},	/* intel2 */
  };
  
  /* Table of language-specific options.  */
***************
*** 756,761 ****
--- 825,833 ----
  FILE *sched_dump_file;
  FILE *local_reg_dump_file;
  FILE *global_reg_dump_file;
+ FILE *memory_simplify_dump_file; /* intel2 */
+ /* intel1 */
+ FILE *loop2_dump_file;
  FILE *sched2_dump_file;
  FILE *jump2_opt_dump_file;
  FILE *dbr_sched_dump_file;
***************
*** 775,780 ****
--- 847,855 ----
  int sched_time;
  int local_alloc_time;
  int global_alloc_time;
+ int memory_simplify_time; /* intel2 */
+ /* intel1 */
+ int loop2_time;
  int sched2_time;
  int dbr_sched_time;
  int shorten_branch_time;
***************
*** 926,931 ****
--- 1001,1010 ----
      fflush (local_reg_dump_file);
    if (global_reg_dump_file)
      fflush (global_reg_dump_file);
+   if (memory_simplify_dump_file) /* intel2 */
+       fflush (memory_simplify_dump_file);
+   if (loop2_dump_file) /* intel1 */
+     fflush (loop2_dump_file);
    if (sched2_dump_file)
      fflush (sched2_dump_file);
    if (jump2_opt_dump_file)
***************
*** 1052,1059 ****
    (*print_error_function) (file);
  
    if (input_file_stack && input_file_stack->next != 0
!       && input_file_stack_tick != last_error_tick
!       && file == input_filename)
      {
        fprintf (stderr, "In file included");
        for (p = input_file_stack->next; p; p = p->next)
--- 1131,1137 ----
    (*print_error_function) (file);
  
    if (input_file_stack && input_file_stack->next != 0
!       && input_file_stack_tick != last_error_tick)
      {
        fprintf (stderr, "In file included");
        for (p = input_file_stack->next; p; p = p->next)
***************
*** 1085,1092 ****
      HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
      HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
      HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
!     HOST_WIDE_INT v4 = va_arg(ap, HOST_WIDE_INT);
!     fprintf (stderr, s, v1, v2, v3, v4);
    }
  #endif
  }
--- 1163,1169 ----
      HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
      HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
      HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
!     fprintf (stderr, s, v1, v2, v3);
    }
  #endif
  }
***************
*** 1863,1883 ****
  }
  
  /* Strip off a legitimate source ending from the input string NAME of
!    length LEN.  Rather than having to know the names used by all of
!    our front ends, we strip off an ending of a period followed by one,
!    two, or three characters.  */
  
  void
  strip_off_ending (name, len)
       char *name;
       int len;
  {
!   if (len > 2 && name[len - 2] == '.')
!     name[len - 2] = '\0';
!   else if (len > 3 && name[len - 3] == '.')
!     name[len - 3] = '\0';
!   else if (len > 4 && name[len - 4] == '.')
!     name[len - 4] = '\0';
  }
  
  /* Output a quoted string.  */
--- 1940,1978 ----
  }
  
  /* Strip off a legitimate source ending from the input string NAME of
!    length LEN. */
  
  void
  strip_off_ending (name, len)
       char *name;
       int len;
  {
!   if (len > 2 && ! strcmp (".c", name + len - 2))
!     name[len - 2] = 0;
!   else if (len > 2 && ! strcmp (".m", name + len - 2))
!     name[len - 2] = 0;
!   else if (len > 2 && ! strcmp (".i", name + len - 2))
!     name[len - 2] = 0;
!   else if (len > 3 && ! strcmp (".ii", name + len - 3))
!     name[len - 3] = 0;
!   else if (len > 3 && ! strcmp (".co", name + len - 3))
!     name[len - 3] = 0;
!   else if (len > 3 && ! strcmp (".cc", name + len - 3))
!     name[len - 3] = 0;
!   else if (len > 2 && ! strcmp (".C", name + len - 2))
!     name[len - 2] = 0;
!   else if (len > 4 && ! strcmp (".cxx", name + len - 4))
!     name[len - 4] = 0;
!   else if (len > 4 && ! strcmp (".cpp", name + len - 4))
!     name[len - 4] = 0;
!   else if (len > 2 && ! strcmp (".f", name + len - 2))
!     name[len - 2] = 0;
!   /* Ada will use extensions like .ada, .adb, and .ads, so just test
!      for "ad".  */
!   else if (len > 4 && ! strncmp (".ad", name + len - 4, 3))
!     name[len - 4] = 0;
!   else if (len > 4 && ! strcmp (".atr", name + len - 4))
!     name[len - 4] = 0;
  }
  
  /* Output a quoted string.  */
***************
*** 1984,1989 ****
--- 2079,2087 ----
    sched_time = 0;
    local_alloc_time = 0;
    global_alloc_time = 0;
+   memory_simplify_time = 0; /* intel2 */
+   /* intel1 */
+   loop2_time = 0;
    sched2_time = 0;
    dbr_sched_time = 0;
    shorten_branch_time = 0;
***************
*** 2080,2085 ****
--- 2178,2194 ----
    if (global_reg_dump)
      global_reg_dump_file = open_dump_file (dump_base_name, ".greg");
  
+   /* intel1 */
+   /* If loop invariants after greg dump desired, open the output file.  */
+   if (loop2_dump)
+   	loop2_dump_file = open_dump_file(dump_base_name, ".l2" );
+ 
+ /* intel2 - begin */
+   /* If memory_simplify dump desired, open the output file.  */
+   if (memory_simplify_dump)
+   	memory_simplify_dump_file=open_dump_file(dump_base_name, ".msim");
+ /* intel2 - end */
+ 
    /* If 2nd scheduling dump desired, open the output file.  */
    if (sched2_dump)
      sched2_dump_file = open_dump_file (dump_base_name, ".sched2");
***************
*** 2492,2497 ****
--- 2601,2612 ----
    if (global_reg_dump)
      fclose (global_reg_dump_file);
  
+   if (memory_simplify_dump)
+     fclose (memory_simplify_dump_file); /* intel2 */
+ 	
+   if (loop2_dump) /* intel1 */
+     fclose (loop2_dump_file);
+ 
    if (sched2_dump)
      fclose (sched2_dump_file);
  
***************
*** 2520,2547 ****
      {
        fprintf (stderr,"\n");
        print_time ("parse", parse_time);
- 
        if (!output_bytecode)
! 	{
! 	  print_time ("integration", integration_time);
! 	  print_time ("jump", jump_time);
! 	  print_time ("cse", cse_time);
! 	  print_time ("loop", loop_time);
! 	  print_time ("cse2", cse2_time);
! 	  print_time ("flow", flow_time);
! 	  print_time ("combine", combine_time);
! 	  print_time ("sched", sched_time);
! 	  print_time ("local-alloc", local_alloc_time);
! 	  print_time ("global-alloc", global_alloc_time);
! 	  print_time ("sched2", sched2_time);
! 	  print_time ("dbranch", dbr_sched_time);
! 	  print_time ("shorten-branch", shorten_branch_time);
! 	  print_time ("stack-reg", stack_reg_time);
! 	  print_time ("final", final_time);
! 	  print_time ("varconst", varconst_time);
! 	  print_time ("symout", symout_time);
! 	  print_time ("dump", dump_time);
! 	}
      }
  }
  
--- 2635,2664 ----
      {
        fprintf (stderr,"\n");
        print_time ("parse", parse_time);
        if (!output_bytecode)
! 	  {
!         print_time ("integration", integration_time);
!         print_time ("jump", jump_time);
!         print_time ("cse", cse_time);
!         print_time ("loop", loop_time);
!         print_time ("cse2", cse2_time);
!         print_time ("flow", flow_time);
!         print_time ("combine", combine_time);
!         print_time ("sched", sched_time);
!         print_time ("local-alloc", local_alloc_time);
!         print_time ("global-alloc", global_alloc_time);
!         print_time ("memory-simplify", memory_simplify_time); /* intel2 */
!         /* intel1 */
!         print_time ("loop2", loop2_time);
!         print_time ("sched2", sched2_time);
!         print_time ("dbranch", dbr_sched_time);
!         print_time ("shorten-branch", shorten_branch_time);
!         print_time ("stack-reg", stack_reg_time);
!         print_time ("final", final_time);
!         print_time ("varconst", varconst_time);
!         print_time ("symout", symout_time);
!         print_time ("dump", dump_time);
!       }
      }
  }
  
***************
*** 2981,2987 ****
  	 and write some of the results to dump file.  */
  
        TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
! 					 flow_dump_file));
        if (warn_uninitialized)
  	{
  	  uninitialized_vars_warning (DECL_INITIAL (decl));
--- 3098,3104 ----
  	 and write some of the results to dump file.  */
  
        TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
! 					 flow_dump_file /* intel2: */, 1));
        if (warn_uninitialized)
  	{
  	  uninitialized_vars_warning (DECL_INITIAL (decl));
***************
*** 3015,3020 ****
--- 3132,3162 ----
  	       fflush (combine_dump_file);
  	     });
  
+   /* intel1 */
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+   if (optimize > 0 && flag_opt_reg_stack)
+     {
+       if(stack_reg_dump)
+         {
+           TIMEVAR (dump_time,
+ 	           {
+ 		     fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
+ 			      IDENTIFIER_POINTER (DECL_NAME (decl)));
+ 	           });
+         }
+       opt_reg_stack();
+       if(stack_reg_dump)
+         {
+           TIMEVAR (dump_time,
+ 	           {
+ 		     print_rtl (stack_reg_dump_file, insns);
+ 		     fflush (stack_reg_dump_file);
+ 	           });
+         }
+     }
+ #endif
+ #endif
    /* Print function header into sched dump now
       because doing the sched analysis makes some of the dump.  */
  
***************
*** 3082,3087 ****
--- 3224,3235 ----
  	       failure = reload (insns, 0, global_reg_dump_file);
  	   });
  
+  /* intel1 */
+   if(optimize > 0 && flag_reg_reg_copy_opt)
+     {
+ 	  reg_to_reg_copy_opt(insns, global_reg_dump_file);
+     }  
+ 
    if (global_reg_dump)
      TIMEVAR (dump_time,
  	     {
***************
*** 3095,3100 ****
--- 3243,3312 ----
  
    reload_completed = 1;
  
+ #ifdef STACK_REGS
+   /* intel1 */
+   if (optimize > 0 && flag_opt_reg_stack)
+     {
+       TIMEVAR (stack_reg_time, float_to_int_cmp (insns, 0));
+     }
+ #endif
+ 
+   /* intel1 */
+   if (loop2_dump)
+     TIMEVAR (dump_time,
+ 	     {
+ 	       fprintf (loop2_dump_file, "\n;; Function %s\n\n",
+ 			IDENTIFIER_POINTER (DECL_NAME (decl)));
+ 	     });
+ 
+   if(optimize>0 && flag_loop_after_global) 
+   {
+       TIMEVAR (loop2_time,
+ 	       {
+ 	         /* intel2 - begin */
+ 	         if (flag_replace_reload_regs)
+ 	           replace_reload_registers (get_insns(),
+ 				             loop2_dump ? loop2_dump_file : 0);
+ 	         /* intel2 - end */
+                  loop_after_global(get_insns(),loop2_dump ? loop2_dump_file : 0); 
+ 	       });
+   }
+   if (optimize>0 && flag_peep_spills)
+     {
+      TIMEVAR (loop2_time,
+ 	      {
+ 	      peep_spills(get_insns(),loop2_dump ? loop2_dump_file : 0); 
+ 	      });
+     }
+     
+   /* Dump rtl code after loop2 opt, if we are doing that.  */
+ 
+   if (loop2_dump && flag_loop_after_global)
+     TIMEVAR (dump_time,
+ 	     {
+ 	       print_rtl (loop2_dump_file, insns);
+ 	       fflush (loop2_dump_file);
+ 	     });
+ 
+ /* intel2 - begin */
+   if (optimize>0 && flag_risc)
+     {
+       if (memory_simplify_dump)
+         TIMEVAR (dump_time,
+ 	         fprintf (memory_simplify_dump_file, "\n;; Function %s\n\n",
+ 		          IDENTIFIER_POINTER (DECL_NAME (decl))));
+     
+   	    TIMEVAR (memory_simplify_time,
+ 	       memory_simplify (memory_simplify_dump ? memory_simplify_dump_file : 0,
+ 							    insns));
+       if (memory_simplify_dump)
+         TIMEVAR (dump_time,
+ 	         {
+ 	           print_rtl (memory_simplify_dump_file, insns);
+ 	           fflush (memory_simplify_dump_file);
+ 	         });
+     }
+ /* intel2 - end */
    /* On some machines, the prologue and epilogue code, or parts thereof,
       can be represented as RTL.  Doing so lets us schedule insns between
       it and the rest of the code and also allows delayed branch
***************
*** 3126,3131 ****
--- 3338,3350 ----
  		 });
      }
  
+   /* intel2 - begin */
+   /* Combine those riscified insns that were not used for scheduling */
+   if (flag_risc && flag_recombine)
+     combine_unscheded (get_insns (),max_reg_num ());
+   /* intel2 - end */
+ 
+ 
  #ifdef LEAF_REGISTERS
    leaf_function = 0;
    if (optimize > 0 && only_leaf_regs_used () && leaf_function_p ())
***************
*** 3185,3190 ****
--- 3404,3414 ----
  	   });
  
  #ifdef STACK_REGS
+   /* intel1 */
+   if (optimize > 0 && flag_opt_reg_stack)
+     {
+       TIMEVAR (stack_reg_time, float_to_int_cmp (insns));
+     }
    TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file));
    if (stack_reg_dump)
      {
***************
*** 3196,3201 ****
--- 3420,3432 ----
  		 fflush (stack_reg_dump_file);
  	       });
      }
+ /* intel1 spl */
+ #ifdef STORE_NOT_SET_CC0
+   if(flag_sftwr_pipe)
+     {
+       do_spl(insns);
+     }
+ #endif
  #endif
  
    /* Now turn the rtl into assembler code.  */
***************
*** 3267,3275 ****
  
    reload_completed = 0;
  
-   /* Clear out the insn_length contents now that they are no longer valid.  */
-   init_insn_lengths ();
- 
    /* Clear out the real_constant_chain before some of the rtx's
       it runs through become garbage.  */
  
--- 3498,3503 ----
***************
*** 3451,3460 ****
--- 3679,3690 ----
   		    dbr_sched_dump = 1;
   		    flow_dump = 1;
   		    global_reg_dump = 1;
+ 		    memory_simplify_dump = 1; /* intel2 */
   		    jump_opt_dump = 1;
   		    jump2_opt_dump = 1;
   		    local_reg_dump = 1;
   		    loop_dump = 1;
+  		    loop2_dump = 1; /* intel1 */
   		    rtl_dump = 1;
   		    cse_dump = 1, cse2_dump = 1;
   		    sched_dump = 1;
***************
*** 3476,3481 ****
--- 3706,3716 ----
  		  case 'g':
  		    global_reg_dump = 1;
  		    break;
+ 		  /* intel2 - begin */
+ 		  case 'b':
+ 		    memory_simplify_dump = 1;
+ 		    break;
+ 		  /* intel2 - end */
  		  case 'j':
  		    jump_opt_dump = 1;
  		    break;
***************
*** 3488,3493 ****
--- 3723,3732 ----
  		  case 'L':
  		    loop_dump = 1;
  		    break;
+ 		    /* intel1 */
+ 		  case 'A':
+ 		    loop2_dump = 1;
+ 		    break;
  		  case 'm':
  		    flag_print_mem = 1;
  		    break;
***************
*** 3791,3798 ****
  		use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
  #endif	      
  	      if (write_symbols == NO_DEBUG)
! 		warning ("`-%s' not supported by this configuration of GCC",
! 			 str);
  	      else if (level == 0)
  		write_symbols = NO_DEBUG;
  	      else
--- 4030,4036 ----
  		use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
  #endif	      
  	      if (write_symbols == NO_DEBUG)
! 		warning ("`-%s' option not supported on this version of GCC", str);
  	      else if (level == 0)
  		write_symbols = NO_DEBUG;
  	      else
***************
*** 3827,3833 ****
      {
  #ifndef TARGET_SUPPORTS_BYTECODE
        /* Just die with a fatal error if not supported */
!       fatal ("-fbytecode not supporter for this target");
  #else
        bc_initialize ();
  #endif
--- 4065,4071 ----
      {
  #ifndef TARGET_SUPPORTS_BYTECODE
        /* Just die with a fatal error if not supported */
!       fatal ("-fbytecode not supported for this target");
  #else
        bc_initialize ();
  #endif
***************
*** 3851,3857 ****
    if (write_symbols == DWARF_DEBUG
        && strcmp (language_string, "GNU C++") == 0)
      {
!       warning ("-g option not supported for C++ on systems using the DWARF debugging format");
        write_symbols = NO_DEBUG;
      }
  #endif /* defined(DWARF_DEBUGGING_INFO) */
--- 4089,4095 ----
    if (write_symbols == DWARF_DEBUG
        && strcmp (language_string, "GNU C++") == 0)
      {
!       warning ("-g option not supported for C++ on SVR4 systems");
        write_symbols = NO_DEBUG;
      }
  #endif /* defined(DWARF_DEBUGGING_INFO) */
***************
*** 3893,3898 ****
--- 4131,4139 ----
  #ifdef TARGET_VERSION
        TARGET_VERSION;
  #endif
+ #ifdef SUB_TARGET_VERSION
+       SUB_TARGET_VERSION;
+ #endif
  #ifdef __GNUC__
  #ifndef __VERSION__
  #define __VERSION__ "[unknown]"
***************
*** 3910,3915 ****
--- 4151,4159 ----
  #if !defined(OS2) && !defined(VMS) && !defined(_WIN32)
    if (flag_print_mem)
      {
+ #ifdef __alpha
+       char *sbrk ();
+ #endif
        char *lim = (char *) sbrk (0);
  
        fprintf (stderr, "Data size %d.\n",
diff -rNci gcc-2.7.2/tree.c gcc-2.7.2p/tree.c
*** gcc-2.7.2/tree.c	Mon Oct  2 01:26:56 1995
--- gcc-2.7.2p/tree.c	Thu Jun 15 12:10:23 1995
***************
*** 2058,2070 ****
      case BIT_FIELD_REF:
        return staticp (TREE_OPERAND (arg, 0));
  
- #if 0
-        /* This case is technically correct, but results in setting
- 	  TREE_CONSTANT on ADDR_EXPRs that cannot be evaluated at
- 	  compile time.  */
      case INDIRECT_REF:
        return TREE_CONSTANT (TREE_OPERAND (arg, 0));
- #endif
  
      case ARRAY_REF:
        if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
--- 2058,2065 ----
***************
*** 2115,2121 ****
       literal node. */
  
    if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
!       || TREE_CODE (t) == SAVE_EXPR || TREE_CODE (t) == ERROR_MARK)
      return t;
  
    /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
--- 2110,2116 ----
       literal node. */
  
    if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
!       || TREE_CODE (t) == SAVE_EXPR)
      return t;
  
    /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
***************
*** 3598,3604 ****
       handled above.  If this is a language-specific tree code, we can't
       trust what might be in the operand, so say we don't know
       the situation.  */
!   if ((int) code1
        >= sizeof standard_tree_code_type / sizeof standard_tree_code_type[0])
      return -1;
  
--- 3593,3599 ----
       handled above.  If this is a language-specific tree code, we can't
       trust what might be in the operand, so say we don't know
       the situation.  */
!   if (code1
        >= sizeof standard_tree_code_type / sizeof standard_tree_code_type[0])
      return -1;
  
diff -rNci gcc-2.7.2/tree.h gcc-2.7.2p/tree.h
*** gcc-2.7.2/tree.h	Mon Sep 25 21:49:40 1995
--- gcc-2.7.2p/tree.h	Thu Jun 15 12:10:49 1995
***************
*** 1289,1295 ****
  extern tree size_int			PROTO((unsigned HOST_WIDE_INT));
  extern tree round_up			PROTO((tree, int));
  extern tree get_pending_sizes		PROTO((void));
- extern void put_pending_sizes		PROTO((tree));
  
  /* Type for sizes of data-type.  */
  
--- 1289,1294 ----
***************
*** 1298,1304 ****
  /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  extern int maximum_field_alignment;
  
! /* If non-zero, the alignment of a bitstring or (power-)set value, in bits. */
  extern int set_alignment;
  
  /* Concatenate two lists (chains of TREE_LIST nodes) X and Y
--- 1297,1303 ----
  /* If nonzero, an upper limit on alignment of structure fields, in bits. */
  extern int maximum_field_alignment;
  
! /* If non-zero, the alignment of a bitsting or (power-)set value, in bits. */
  extern int set_alignment;
  
  /* Concatenate two lists (chains of TREE_LIST nodes) X and Y
diff -rNci gcc-2.7.2/unroll.c gcc-2.7.2p/unroll.c
*** gcc-2.7.2/unroll.c	Sat Aug 19 21:33:26 1995
--- gcc-2.7.2p/unroll.c	Tue Jan 23 09:25:32 1996
***************
*** 156,161 ****
--- 156,164 ----
  #include <stdio.h>
  #include "loop.h"
  
+ /* intel1 */
+ extern FILE *loop_dump_stream;
+ 
  /* This controls which loops are unrolled, and by how much we unroll
     them.  */
  
***************
*** 853,871 ****
  	  for (i = 0; i < unroll_number; i++)
  	    labels[i] = gen_label_rtx ();
  
- 	  /* Check for the case where the initial value is greater than or equal
- 	     to the final value.  In that case, we want to execute exactly
- 	     one loop iteration.  The code below will fail for this case.  */
- 
- 	  emit_cmp_insn (initial_value, final_value, neg_inc ? LE : GE,
- 			 NULL_RTX, mode, 0, 0);
- 	  if (neg_inc)
- 	    emit_jump_insn (gen_ble (labels[1]));
- 	  else
- 	    emit_jump_insn (gen_bge (labels[1]));
- 	  JUMP_LABEL (get_last_insn ()) = labels[1];
- 	  LABEL_NUSES (labels[1])++;
- 
  	  /* Assuming the unroll_number is 4, and the increment is 2, then
  	     for a negative increment:	for a positive increment:
  	     diff = 0,1   precond 0	diff = 0,7   precond 0
--- 856,861 ----
***************
*** 882,909 ****
  	  for (i = 0; i < unroll_number - 1; i++)
  	    {
  	      int cmp_const;
- 	      enum rtx_code cmp_code;
  
  	      /* For negative increments, must invert the constant compared
  		 against, except when comparing against zero.  */
  	      if (i == 0)
! 		{
! 		  cmp_const = 0;
! 		  cmp_code = EQ;
! 		}
  	      else if (neg_inc)
! 		{
! 		  cmp_const = unroll_number - i;
! 		  cmp_code = GE;
! 		}
  	      else
! 		{
! 		  cmp_const = i;
! 		  cmp_code = LE;
! 		}
  
  	      emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
! 			     cmp_code, NULL_RTX, mode, 0, 0);
  
  	      if (i == 0)
  		emit_jump_insn (gen_beq (labels[i]));
--- 872,889 ----
  	  for (i = 0; i < unroll_number - 1; i++)
  	    {
  	      int cmp_const;
  
  	      /* For negative increments, must invert the constant compared
  		 against, except when comparing against zero.  */
  	      if (i == 0)
! 		cmp_const = 0;
  	      else if (neg_inc)
! 		cmp_const = unroll_number - i;
  	      else
! 		cmp_const = i;
  
  	      emit_cmp_insn (diff, GEN_INT (abs_inc * cmp_const),
! 			     EQ, NULL_RTX, mode, 0, 0);
  
  	      if (i == 0)
  		emit_jump_insn (gen_beq (labels[i]));
***************
*** 927,946 ****
  	  if (abs_inc != 1)
  	    {
  	      int cmp_const;
- 	      enum rtx_code cmp_code;
  
  	      if (neg_inc)
! 		{
! 		  cmp_const = abs_inc - 1;
! 		  cmp_code = LE;
! 		}
  	      else
! 		{
! 		  cmp_const = abs_inc * (unroll_number - 1) + 1;
! 		  cmp_code = GE;
! 		}
  
! 	      emit_cmp_insn (diff, GEN_INT (cmp_const), cmp_code, NULL_RTX,
  			     mode, 0, 0);
  
  	      if (neg_inc)
--- 907,919 ----
  	  if (abs_inc != 1)
  	    {
  	      int cmp_const;
  
  	      if (neg_inc)
! 		cmp_const = abs_inc - 1;
  	      else
! 		cmp_const = abs_inc * (unroll_number - 1) + 1;
  
! 	      emit_cmp_insn (diff, GEN_INT (cmp_const), EQ, NULL_RTX,
  			     mode, 0, 0);
  
  	      if (neg_inc)
***************
*** 1412,1424 ****
  	 one of the LO_SUM rtx.  */
        if (GET_CODE (increment) == LO_SUM)
  	increment = XEXP (increment, 1);
!       else if (GET_CODE (increment) == IOR
! 	       || GET_CODE (increment) == ASHIFT)
  	{
! 	  /* The rs6000 port loads some constants with IOR.
! 	     The alpha port loads some constants with ASHIFT.  */
  	  rtx second_part = XEXP (increment, 1);
- 	  enum rtx_code code = GET_CODE (increment);
  
  	  src_insn = PREV_INSN (src_insn);
  	  increment = SET_SRC (PATTERN (src_insn));
--- 1385,1394 ----
  	 one of the LO_SUM rtx.  */
        if (GET_CODE (increment) == LO_SUM)
  	increment = XEXP (increment, 1);
!       else if (GET_CODE (increment) == IOR)
  	{
! 	  /* The rs6000 port loads some constants with IOR.  */
  	  rtx second_part = XEXP (increment, 1);
  
  	  src_insn = PREV_INSN (src_insn);
  	  increment = SET_SRC (PATTERN (src_insn));
***************
*** 1429,1438 ****
  	      || GET_CODE (increment) != CONST_INT)
  	    abort ();
  
! 	  if (code == IOR)
! 	    increment = GEN_INT (INTVAL (increment) | INTVAL (second_part));
! 	  else
! 	    increment = GEN_INT (INTVAL (increment) << INTVAL (second_part));
  	}
  
        if (GET_CODE (increment) != CONST_INT)
--- 1399,1405 ----
  	      || GET_CODE (increment) != CONST_INT)
  	    abort ();
  
! 	  increment = GEN_INT (INTVAL (increment) | INTVAL (second_part));
  	}
  
        if (GET_CODE (increment) != CONST_INT)
***************
*** 1770,1775 ****
--- 1737,1778 ----
  	  else
  	    {
  	      pattern = copy_rtx_and_substitute (pattern, map);
+ /* intel1 since a DEST_ADDR giv may be only a part of an address
+    then just substituting reg+const for reg may result in an
+    invalid insn - we check for that and try to make it good */
+ #if REDUCE_INDEX || SAVE_ON_REGS
+               if(GET_CODE(PATTERN(insn))==SET)
+ 	        {
+ 	          int dummy;
+ 	          rtx try_to_make_good(); /* see loop.c */
+ 	          if(recog(pattern,insn,&dummy)==-1)
+ 	            {
+ 	              try_to_make_good(SET_SRC(pattern));
+ 	              try_to_make_good(SET_DEST(pattern));
+   	              if(recog(pattern,insn,&dummy)==-1)
+   	              {
+   	                fprintf(stderr,"bad pattern in insn not better:\n");
+   	                debug_rtx(insn);
+   	                abort();
+   	              }
+ 	            }
+ 	        }
+ #endif
+ 	      /* intel1 Don't want to be reusing STACK_MODE registers
+ 	         since that inhibits scheduling opportunities */
+ #ifdef STACK_REGS
+ #ifdef IS_STACK_MODE
+ #ifdef ONLY_STACK_REG_REORDER
+             if (GET_CODE (pattern) == SET && GET_CODE (SET_DEST (pattern)) == REG
+                 && IS_STACK_MODE (GET_MODE (SET_DEST (pattern))))
+               {
+ 	        tem = gen_reg_rtx (GET_MODE (SET_DEST (pattern)));
+ 	        map->reg_map[REGNO (SET_DEST (PATTERN (insn)))] = tem;
+ 	        SET_DEST (pattern) = tem;
+               }
+ #endif
+ #endif
+ #endif
  	      copy = emit_insn (pattern);
  	    }
  	  REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
***************
*** 2393,2405 ****
  	 it is unsafe to split the biv since it may not have the proper
  	 value on loop exit.  */
  
!       /* loop_number_exit_count is non-zero if the loop has an exit other than
  	 a fall through at the end.  */
  
        biv_splittable = 1;
        biv_final_value = 0;
        if (unroll_type != UNROLL_COMPLETELY
! 	  && (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
  	      || unroll_type == UNROLL_NAIVE)
  	  && (uid_luid[regno_last_uid[bl->regno]] >= INSN_LUID (loop_end)
  	      || ! bl->init_insn
--- 2396,2408 ----
  	 it is unsafe to split the biv since it may not have the proper
  	 value on loop exit.  */
  
!       /* loop_number_exit_labels is non-zero if the loop has an exit other than
  	 a fall through at the end.  */
  
        biv_splittable = 1;
        biv_final_value = 0;
        if (unroll_type != UNROLL_COMPLETELY
! 	  && (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
  	      || unroll_type == UNROLL_NAIVE)
  	  && (uid_luid[regno_last_uid[bl->regno]] >= INSN_LUID (loop_end)
  	      || ! bl->init_insn
***************
*** 2433,2445 ****
  	    {
  	      /* If the initial value of the biv is itself (i.e. it is too
  		 complicated for strength_reduce to compute), or is a hard
! 		 register, or it isn't invariant, then we must create a new
! 		 pseudo reg to hold the initial value of the biv.  */
  
  	      if (GET_CODE (bl->initial_value) == REG
  		  && (REGNO (bl->initial_value) == bl->regno
! 		      || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER
! 		      || ! invariant_p (bl->initial_value)))
  		{
  		  rtx tem = gen_reg_rtx (bl->biv->mode);
  		  
--- 2436,2447 ----
  	    {
  	      /* If the initial value of the biv is itself (i.e. it is too
  		 complicated for strength_reduce to compute), or is a hard
! 		 register, then we must create a new pseudo reg to hold the
! 		 initial value of the biv.  */
  
  	      if (GET_CODE (bl->initial_value) == REG
  		  && (REGNO (bl->initial_value) == bl->regno
! 		      || REGNO (bl->initial_value) < FIRST_PSEUDO_REGISTER))
  		{
  		  rtx tem = gen_reg_rtx (bl->biv->mode);
  		  
***************
*** 2487,2493 ****
  	     loop to ensure that it will always be executed no matter
  	     how the loop exits.  Otherwise emit the insn after the loop,
  	     since this is slightly more efficient.  */
! 	  if (! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
  	    emit_insn_before (gen_move_insn (bl->biv->src_reg,
  					     biv_final_value),
  			      end_insert_before);
--- 2489,2495 ----
  	     loop to ensure that it will always be executed no matter
  	     how the loop exits.  Otherwise emit the insn after the loop,
  	     since this is slightly more efficient.  */
! 	  if (! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
  	    emit_insn_before (gen_move_insn (bl->biv->src_reg,
  					     biv_final_value),
  			      end_insert_before);
***************
*** 2610,2616 ****
  
        final_value = 0;
        if (unroll_type != UNROLL_COMPLETELY
! 	  && (loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
  	      || unroll_type == UNROLL_NAIVE)
  	  && v->giv_type != DEST_ADDR
  	  && ((regno_first_uid[REGNO (v->dest_reg)] != INSN_UID (v->insn)
--- 2612,2618 ----
  
        final_value = 0;
        if (unroll_type != UNROLL_COMPLETELY
! 	  && (loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
  	      || unroll_type == UNROLL_NAIVE)
  	  && v->giv_type != DEST_ADDR
  	  && ((regno_first_uid[REGNO (v->dest_reg)] != INSN_UID (v->insn)
***************
*** 2950,2975 ****
    rtx insn, label;
    enum rtx_code code;
    int jump_count = 0;
-   int label_count = 0;
-   int this_loop_num = uid_loop_num[INSN_UID (loop_start)];
- 
-   /* In addition to checking all exits of this loop, we must also check
-      all exits of inner nested loops that would exit this loop.  We don't
-      have any way to identify those, so we just give up if there are any
-      such inner loop exits.  */
-      
-   for (label = loop_number_exit_labels[this_loop_num]; label;
-        label = LABEL_NEXTREF (label))
-     label_count++;
- 
-   if (label_count != loop_number_exit_count[this_loop_num])
-     return 0;
  
    /* HACK: Must also search the loop fall through exit, create a label_ref
       here which points to the loop_end, and append the loop_number_exit_labels
       list to it.  */
    label = gen_rtx (LABEL_REF, VOIDmode, loop_end);
!   LABEL_NEXTREF (label) = loop_number_exit_labels[this_loop_num];
  
    for ( ; label; label = LABEL_NEXTREF (label))
      {
--- 2952,2964 ----
    rtx insn, label;
    enum rtx_code code;
    int jump_count = 0;
  
    /* HACK: Must also search the loop fall through exit, create a label_ref
       here which points to the loop_end, and append the loop_number_exit_labels
       list to it.  */
    label = gen_rtx (LABEL_REF, VOIDmode, loop_end);
!   LABEL_NEXTREF (label)
!     = loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]];
  
    for ( ; label; label = LABEL_NEXTREF (label))
      {
***************
*** 3048,3054 ****
       value of the biv must be invariant.  */
  
    if (loop_n_iterations != 0
!       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]]
        && invariant_p (bl->initial_value))
      {
        increment = biv_total_increment (bl, loop_start, loop_end);
--- 3037,3043 ----
       value of the biv must be invariant.  */
  
    if (loop_n_iterations != 0
!       && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]]
        && invariant_p (bl->initial_value))
      {
        increment = biv_total_increment (bl, loop_start, loop_end);
***************
*** 3126,3132 ****
       to be known.  */
  
    if (loop_n_iterations != 0
!       && ! loop_number_exit_count[uid_loop_num[INSN_UID (loop_start)]])
      {
        /* ?? It is tempting to use the biv's value here since these insns will
  	 be put after the loop, and hence the biv will have its final value
--- 3115,3121 ----
       to be known.  */
  
    if (loop_n_iterations != 0
!       && ! loop_number_exit_labels[uid_loop_num[INSN_UID (loop_start)]])
      {
        /* ?? It is tempting to use the biv's value here since these insns will
  	 be put after the loop, and hence the biv will have its final value
diff -rNci gcc-2.7.2/varasm.c gcc-2.7.2p/varasm.c
*** gcc-2.7.2/varasm.c	Thu Aug 31 23:02:53 1995
--- gcc-2.7.2p/varasm.c	Tue Jan 23 09:25:32 1996
***************
*** 78,90 ****
  
  /* Number for making the label on the next
     constant that is stored in memory.  */
! 
! int const_labelno;
  
  /* Number for making the label on the next
     static variable internal to a function.  */
! 
! int var_labelno;
  
  /* Carry information from ASM_DECLARE_OBJECT_NAME
     to ASM_FINISH_DECLARE_OBJECT.  */
--- 78,90 ----
  
  /* Number for making the label on the next
     constant that is stored in memory.  */
! /* intel1 */
! static int const_labelno = 0;
  
  /* Number for making the label on the next
     static variable internal to a function.  */
! /* intel1 */
! int var_labelno = 0;
  
  /* Carry information from ASM_DECLARE_OBJECT_NAME
     to ASM_FINISH_DECLARE_OBJECT.  */
***************
*** 1147,1158 ****
  	    else
  	      {
  #ifdef ASM_OUTPUT_ALIGNED_COMMON
! 		ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
! 					   DECL_ALIGN (decl));
  #else
! 		ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
  #endif
! 	      }
  	}
        else
  	{
--- 1147,1169 ----
  	    else
  	      {
  #ifdef ASM_OUTPUT_ALIGNED_COMMON
! /* intel1 */
! #ifdef ALIGN_DFmode
!               if (DECL_MODE (decl) == DFmode
!                   && DECL_ALIGN (decl) 
!                     == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
!                 {
! 	      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, 
! 	      GET_MODE_SIZE (DFmode) * BITS_PER_UNIT);
!                 }
!               else
! #endif
! 	      ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
! 	 	 		         DECL_ALIGN (decl));
  #else
! 	      ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
  #endif
! 		}
  	}
        else
  	{
***************
*** 1168,1179 ****
  	    else
  	      {
  #ifdef ASM_OUTPUT_ALIGNED_LOCAL
! 		ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
! 					  DECL_ALIGN (decl));
  #else
! 		ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  #endif
! 	      }
  	}
        goto finish;
      }
--- 1179,1201 ----
  	    else
  	      {
  #ifdef ASM_OUTPUT_ALIGNED_LOCAL
! /* intel1 */
! #ifdef ALIGN_DFmode
!             if (DECL_MODE (decl) == DFmode
!                 && DECL_ALIGN (decl) 
!                   == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
!               {
! 	    ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, 
! 	    GET_MODE_SIZE (DFmode) * BITS_PER_UNIT);
!               }
!             else
! #endif
! 	    ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size,
! 				      DECL_ALIGN (decl));
  #else
! 	    ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
  #endif
! 		}
  	}
        goto finish;
      }
***************
*** 1327,1332 ****
--- 1349,1362 ----
       from it in get_pointer_alignment.  */
    DECL_ALIGN (decl) = align;
  
+ /* intel1 */
+ #ifdef ALIGN_DFmode
+     if (DECL_MODE (decl) == DFmode
+         && DECL_ALIGN (decl) == (GET_MODE_SIZE (SFmode) * BITS_PER_UNIT))
+       {
+         align = GET_MODE_SIZE (DFmode) * BITS_PER_UNIT;
+       }
+ #endif
    if (align > BITS_PER_UNIT)
      {
        if (output_bytecode)
***************
*** 1575,1581 ****
    if (name[0] == '*')
      {
        if (output_bytecode)
! 	bc_emit_labelref (name, 0);
        else
  	fputs (&name[1], file);
      }
--- 1605,1611 ----
    if (name[0] == '*')
      {
        if (output_bytecode)
! 	bc_emit_labelref (name);
        else
  	fputs (&name[1], file);
      }
***************
*** 2954,2960 ****
    union {
      union real_extract du;
      struct addr_const addr;
-     struct {HOST_WIDE_INT high, low;} di;
    } un;
  };
  
--- 2984,2989 ----
***************
*** 2985,3000 ****
      case CONST_DOUBLE:
        value->kind = RTX_DOUBLE;
        if (GET_MODE (x) != VOIDmode)
! 	{
! 	  value->mode = GET_MODE (x);
! 	  bcopy ((char *) &CONST_DOUBLE_LOW (x),
! 		 (char *) &value->un.du, sizeof value->un.du);
! 	}
!       else
! 	{
! 	  value->un.di.low = CONST_DOUBLE_LOW (x);
! 	  value->un.di.high = CONST_DOUBLE_HIGH (x);
! 	}
        break;
  
      case CONST_INT:
--- 3014,3022 ----
      case CONST_DOUBLE:
        value->kind = RTX_DOUBLE;
        if (GET_MODE (x) != VOIDmode)
! 	value->mode = GET_MODE (x);
!       bcopy ((char *) &CONST_DOUBLE_LOW (x),
! 	     (char *) &value->un.du, sizeof value->un.du);
        break;
  
      case CONST_INT:
***************
*** 3198,3203 ****
--- 3220,3229 ----
        align = (mode == VOIDmode) ? UNITS_PER_WORD : GET_MODE_SIZE (mode);
        if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
  	align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
+       /* intel1 */
+ #ifdef ALIGN_DFmode
+       align = (mode == DFmode) ? GET_MODE_SIZE (mode) : align;
+ #endif
  
        pool_offset += align - 1;
        pool_offset &= ~ (align - 1);
***************
*** 3693,3700 ****
    else
      if (size == 4
  	&& TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
!       bc_emit_labelref (IDENTIFIER_POINTER
! 			(DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0))),
  			TREE_INT_CST_LOW (const_part));
      else
        abort ();		/* FIXME: there may be more cases.  */
--- 3719,3725 ----
    else
      if (size == 4
  	&& TREE_CODE (TREE_OPERAND (addr_part, 0)) == VAR_DECL)
!       bc_emit_labelref (DECL_ASSEMBLER_NAME (TREE_OPERAND (addr_part, 0)),
  			TREE_INT_CST_LOW (const_part));
      else
        abort ();		/* FIXME: there may be more cases.  */
diff -rNci gcc-2.7.2/version.c gcc-2.7.2p/version.c
*** gcc-2.7.2/version.c	Sun Nov 26 16:20:43 1995
--- gcc-2.7.2p/version.c	Tue Jan 23 09:54:59 1996
***************
*** 1 ****
! char *version_string = "2.7.2";
--- 1 ----
! char *version_string = "2.7.2p";
